kopia lustrzana https://github.com/Schildkroet/GRBL-Advanced
rodzic
05d4c30570
commit
752f0e404d
|
@ -221,6 +221,35 @@
|
|||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="HAL\USART\USART.h" />
|
||||
<Unit filename="Libraries\CRC\CRC.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="Libraries\CRC\CRC.h" />
|
||||
<Unit filename="Libraries\Ethernet\Ethernet.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="Libraries\Ethernet\Ethernet.h" />
|
||||
<Unit filename="Libraries\Ethernet\ServerTCP.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="Libraries\Ethernet\ServerTCP.h" />
|
||||
<Unit filename="Libraries\Ethernet\utility\socket.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="Libraries\Ethernet\utility\socket.h" />
|
||||
<Unit filename="Libraries\Ethernet\utility\util2.h" />
|
||||
<Unit filename="Libraries\Ethernet\utility\W5500.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="Libraries\Ethernet\utility\W5500.h" />
|
||||
<Unit filename="Libraries\GrIP\ComIf.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="Libraries\GrIP\ComIf.h" />
|
||||
<Unit filename="Libraries\GrIP\GrIP.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="Libraries\GrIP\GrIP.h" />
|
||||
<Unit filename="main.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<Cursor1 position="1639" topLine="32" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="grbl\Config.h" open="1" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<File name="grbl\Config.h" open="1" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="36781" topLine="531" />
|
||||
</Cursor>
|
||||
|
@ -36,7 +36,7 @@
|
|||
<Cursor1 position="873" topLine="13" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="grbl\defaults.h" open="1" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<File name="grbl\defaults.h" open="1" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="2407" topLine="10" />
|
||||
</Cursor>
|
||||
|
@ -116,12 +116,12 @@
|
|||
<Cursor1 position="842" topLine="3" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="grbl\Report.c" open="1" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<File name="grbl\Report.c" open="1" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="7135" topLine="235" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="grbl\Report.h" open="1" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<File name="grbl\Report.h" open="1" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="1483" topLine="9" />
|
||||
</Cursor>
|
||||
|
@ -156,17 +156,17 @@
|
|||
<Cursor1 position="875" topLine="0" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="grbl\System.c" open="1" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<File name="grbl\System.c" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="7435" topLine="208" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="grbl\System.h" open="1" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<File name="grbl\System.h" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="4260" topLine="53" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="grbl\ToolChange.c" open="1" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<File name="grbl\ToolChange.c" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="2162" topLine="66" />
|
||||
</Cursor>
|
||||
|
@ -296,9 +296,9 @@
|
|||
<Cursor1 position="781" topLine="12" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="main.c" open="1" top="1" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<File name="main.c" open="1" top="1" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="1982" topLine="33" />
|
||||
<Cursor1 position="2509" topLine="62" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="SPL\inc\stm32f4xx_cryp.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
|
@ -356,9 +356,9 @@
|
|||
<Cursor1 position="141" topLine="0" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="Src\Platform.h" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<File name="Src\Platform.h" open="1" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="530" topLine="0" />
|
||||
<Cursor1 position="719" topLine="9" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="Src\Print.c" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
* A5: PROBE_BIT: PC0
|
||||
*/
|
||||
#include "GPIO.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
static void GPIO_InitStepper(void);
|
||||
|
@ -167,6 +168,18 @@ static void GPIO_InitSystem(void)
|
|||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
#ifdef ETH_IF
|
||||
// W5500 Reset Pin
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
GPIO_SetBits(GPIOA, GPIO_Pin_15);
|
||||
#endif
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include "Settings.h"
|
||||
#include "Config.h"
|
||||
#include "MotionControl.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
/** @addtogroup Template_Project
|
||||
* @{
|
||||
|
@ -68,6 +70,59 @@ uint32_t millis(void)
|
|||
}
|
||||
|
||||
|
||||
void ProcessReceive(char c)
|
||||
{
|
||||
// Pick off realtime command characters directly from the serial stream. These characters are
|
||||
// not passed into the main buffer, but these set system state flag bits for realtime execution.
|
||||
switch(c)
|
||||
{
|
||||
case CMD_RESET: MC_Reset(); break; // Call motion control reset routine.
|
||||
case CMD_RESET_HARD: NVIC_SystemReset(); // Perform hard reset
|
||||
case CMD_STATUS_REPORT: System_SetExecStateFlag(EXEC_STATUS_REPORT);break;
|
||||
case CMD_CYCLE_START: System_SetExecStateFlag(EXEC_CYCLE_START); break; // Set as true
|
||||
case CMD_FEED_HOLD: System_SetExecStateFlag(EXEC_FEED_HOLD); break; // Set as true
|
||||
case CMD_STEPPER_DISABLE: Stepper_Disable(1); break; // Set as true
|
||||
|
||||
default:
|
||||
if(c > 0x7F) { // Real-time control characters are extended ACSII only.
|
||||
switch(c)
|
||||
{
|
||||
case CMD_SAFETY_DOOR: System_SetExecStateFlag(EXEC_SAFETY_DOOR); break; // Set as true
|
||||
case CMD_JOG_CANCEL:
|
||||
if(sys.state & STATE_JOG) { // Block all other states from invoking motion cancel.
|
||||
System_SetExecStateFlag(EXEC_MOTION_CANCEL);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_FEED_OVR_RESET: System_SetExecMotionOverrideFlag(EXEC_FEED_OVR_RESET); break;
|
||||
case CMD_FEED_OVR_COARSE_PLUS: System_SetExecMotionOverrideFlag(EXEC_FEED_OVR_COARSE_PLUS); break;
|
||||
case CMD_FEED_OVR_COARSE_MINUS: System_SetExecMotionOverrideFlag(EXEC_FEED_OVR_COARSE_MINUS); break;
|
||||
case CMD_FEED_OVR_FINE_PLUS: System_SetExecMotionOverrideFlag(EXEC_FEED_OVR_FINE_PLUS); break;
|
||||
case CMD_FEED_OVR_FINE_MINUS: System_SetExecMotionOverrideFlag(EXEC_FEED_OVR_FINE_MINUS); break;
|
||||
case CMD_RAPID_OVR_RESET: System_SetExecMotionOverrideFlag(EXEC_RAPID_OVR_RESET); break;
|
||||
case CMD_RAPID_OVR_MEDIUM: System_SetExecMotionOverrideFlag(EXEC_RAPID_OVR_MEDIUM); break;
|
||||
case CMD_RAPID_OVR_LOW: System_SetExecMotionOverrideFlag(EXEC_RAPID_OVR_LOW); break;
|
||||
case CMD_SPINDLE_OVR_RESET: System_SetExecAccessoryOverrideFlag(EXEC_SPINDLE_OVR_RESET); break;
|
||||
case CMD_SPINDLE_OVR_COARSE_PLUS: System_SetExecAccessoryOverrideFlag(EXEC_SPINDLE_OVR_COARSE_PLUS); break;
|
||||
case CMD_SPINDLE_OVR_COARSE_MINUS: System_SetExecAccessoryOverrideFlag(EXEC_SPINDLE_OVR_COARSE_MINUS); break;
|
||||
case CMD_SPINDLE_OVR_FINE_PLUS: System_SetExecAccessoryOverrideFlag(EXEC_SPINDLE_OVR_FINE_PLUS); break;
|
||||
case CMD_SPINDLE_OVR_FINE_MINUS: System_SetExecAccessoryOverrideFlag(EXEC_SPINDLE_OVR_FINE_MINUS); break;
|
||||
case CMD_SPINDLE_OVR_STOP: System_SetExecAccessoryOverrideFlag(EXEC_SPINDLE_OVR_STOP); break;
|
||||
case CMD_COOLANT_FLOOD_OVR_TOGGLE: System_SetExecAccessoryOverrideFlag(EXEC_COOLANT_FLOOD_OVR_TOGGLE); break;
|
||||
#ifdef ENABLE_M7
|
||||
case CMD_COOLANT_MIST_OVR_TOGGLE: System_SetExecAccessoryOverrideFlag(EXEC_COOLANT_MIST_OVR_TOGGLE); break;
|
||||
#endif
|
||||
}
|
||||
// Throw away any unfound extended-ASCII character by not passing it to the serial buffer.
|
||||
}
|
||||
else {
|
||||
// Write character to buffer
|
||||
FifoUsart_Insert(USART2_NUM, USART_DIR_RX, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function handles NMI exception.
|
||||
* @param None
|
||||
|
@ -292,52 +347,7 @@ void USART2_IRQHandler(void)
|
|||
/* Read one byte from the receive data register */
|
||||
unsigned char c = (USART_ReceiveData(USART2) & 0xFF);
|
||||
|
||||
// Pick off realtime command characters directly from the serial stream. These characters are
|
||||
// not passed into the main buffer, but these set system state flag bits for realtime execution.
|
||||
switch(c)
|
||||
{
|
||||
case CMD_RESET: MC_Reset(); break; // Call motion control reset routine.
|
||||
case CMD_RESET_HARD: NVIC_SystemReset(); // Perform hard reset
|
||||
case CMD_STATUS_REPORT: System_SetExecStateFlag(EXEC_STATUS_REPORT);break;
|
||||
case CMD_CYCLE_START: System_SetExecStateFlag(EXEC_CYCLE_START); break; // Set as true
|
||||
case CMD_FEED_HOLD: System_SetExecStateFlag(EXEC_FEED_HOLD); break; // Set as true
|
||||
default:
|
||||
if(c > 0x7F) { // Real-time control characters are extended ACSII only.
|
||||
switch(c)
|
||||
{
|
||||
case CMD_SAFETY_DOOR: System_SetExecStateFlag(EXEC_SAFETY_DOOR); break; // Set as true
|
||||
case CMD_JOG_CANCEL:
|
||||
if(sys.state & STATE_JOG) { // Block all other states from invoking motion cancel.
|
||||
System_SetExecStateFlag(EXEC_MOTION_CANCEL);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_FEED_OVR_RESET: System_SetExecMotionOverrideFlag(EXEC_FEED_OVR_RESET); break;
|
||||
case CMD_FEED_OVR_COARSE_PLUS: System_SetExecMotionOverrideFlag(EXEC_FEED_OVR_COARSE_PLUS); break;
|
||||
case CMD_FEED_OVR_COARSE_MINUS: System_SetExecMotionOverrideFlag(EXEC_FEED_OVR_COARSE_MINUS); break;
|
||||
case CMD_FEED_OVR_FINE_PLUS: System_SetExecMotionOverrideFlag(EXEC_FEED_OVR_FINE_PLUS); break;
|
||||
case CMD_FEED_OVR_FINE_MINUS: System_SetExecMotionOverrideFlag(EXEC_FEED_OVR_FINE_MINUS); break;
|
||||
case CMD_RAPID_OVR_RESET: System_SetExecMotionOverrideFlag(EXEC_RAPID_OVR_RESET); break;
|
||||
case CMD_RAPID_OVR_MEDIUM: System_SetExecMotionOverrideFlag(EXEC_RAPID_OVR_MEDIUM); break;
|
||||
case CMD_RAPID_OVR_LOW: System_SetExecMotionOverrideFlag(EXEC_RAPID_OVR_LOW); break;
|
||||
case CMD_SPINDLE_OVR_RESET: System_SetExecAccessoryOverrideFlag(EXEC_SPINDLE_OVR_RESET); break;
|
||||
case CMD_SPINDLE_OVR_COARSE_PLUS: System_SetExecAccessoryOverrideFlag(EXEC_SPINDLE_OVR_COARSE_PLUS); break;
|
||||
case CMD_SPINDLE_OVR_COARSE_MINUS: System_SetExecAccessoryOverrideFlag(EXEC_SPINDLE_OVR_COARSE_MINUS); break;
|
||||
case CMD_SPINDLE_OVR_FINE_PLUS: System_SetExecAccessoryOverrideFlag(EXEC_SPINDLE_OVR_FINE_PLUS); break;
|
||||
case CMD_SPINDLE_OVR_FINE_MINUS: System_SetExecAccessoryOverrideFlag(EXEC_SPINDLE_OVR_FINE_MINUS); break;
|
||||
case CMD_SPINDLE_OVR_STOP: System_SetExecAccessoryOverrideFlag(EXEC_SPINDLE_OVR_STOP); break;
|
||||
case CMD_COOLANT_FLOOD_OVR_TOGGLE: System_SetExecAccessoryOverrideFlag(EXEC_COOLANT_FLOOD_OVR_TOGGLE); break;
|
||||
#ifdef ENABLE_M7
|
||||
case CMD_COOLANT_MIST_OVR_TOGGLE: System_SetExecAccessoryOverrideFlag(EXEC_COOLANT_MIST_OVR_TOGGLE); break;
|
||||
#endif
|
||||
}
|
||||
// Throw away any unfound extended-ASCII character by not passing it to the serial buffer.
|
||||
}
|
||||
else {
|
||||
// Write character to buffer
|
||||
FifoUsart_Insert(USART2_NUM, USART_DIR_RX, c);
|
||||
}
|
||||
}
|
||||
ProcessReceive(c);
|
||||
}
|
||||
|
||||
if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET) {
|
||||
|
|
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
CRC.c - Simple library to calculate 8-, 16-, and 32-Bit CRC
|
||||
|
||||
Copyright (c) 2018 Patrick F.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) 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.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "CRC.h"
|
||||
|
||||
|
||||
//---- Prototypes ----//
|
||||
static void CRC_CalculateCRC8Table(void);
|
||||
static void CRC_CalculateCRC16Table(void);
|
||||
static void CRC_CalculateCRC32Table(void);
|
||||
|
||||
static uint8_t CRC_ReverseBitOrder8(uint8_t value);
|
||||
static uint32_t CRC_ReverseBitOrder32(uint32_t value);
|
||||
|
||||
|
||||
|
||||
#if (CRC_8_MODE == TABLE)
|
||||
static uint8_t CRC8Table[256u];
|
||||
#endif
|
||||
|
||||
#if (CRC_16_MODE == TABLE)
|
||||
static uint16_t CRC16Table[256u];
|
||||
#endif
|
||||
|
||||
#if (CRC_32_MODE == TABLE)
|
||||
static uint32_t CRC32Table[256u];
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void CRC_Init(void)
|
||||
{
|
||||
CRC_CalculateCRC8Table();
|
||||
CRC_CalculateCRC16Table();
|
||||
CRC_CalculateCRC32Table();
|
||||
}
|
||||
|
||||
|
||||
uint8_t CRC_CalculateCRC8(const uint8_t *Buffer, uint16_t Length)
|
||||
{
|
||||
uint8_t retVal = 0u;
|
||||
uint16_t byteIndex = 0u;
|
||||
|
||||
|
||||
if(Buffer != NULL)
|
||||
{
|
||||
#if (CRC_8_MODE == RUNTTIME)
|
||||
uint8_t bitIndex = 0u;
|
||||
|
||||
retVal = CRC_8_INIT_VALUE;
|
||||
|
||||
/* Do calculation procedure for each byte */
|
||||
for(byteIndex = 0u; byteIndex < Length; byteIndex++)
|
||||
{
|
||||
/* XOR new byte with temp result */
|
||||
retVal ^= (Buffer[byteIndex] << (CRC_8_RESULT_WIDTH - 8u));
|
||||
|
||||
/* Do calculation for current data */
|
||||
for(bitIndex = 0u; bitIndex < 8u; bitIndex++)
|
||||
{
|
||||
if(retVal & (1u << (CRC_8_RESULT_WIDTH - 1u)))
|
||||
{
|
||||
retVal = (retVal << 1u) ^ CRC_8_POLYNOMIAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = (retVal << 1u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* XOR result with specified value */
|
||||
retVal ^= CRC_8_XOR_VALUE;
|
||||
|
||||
#elif (CRC_8_MODE == TABLE)
|
||||
retVal = CRC_8_INIT_VALUE;
|
||||
|
||||
for(byteIndex = 0u; byteIndex < Length; byteIndex++)
|
||||
{
|
||||
retVal = CRC8Table[(retVal) ^ Buffer[byteIndex]];
|
||||
}
|
||||
|
||||
/* XOR result with specified value */
|
||||
retVal ^= CRC_8_XOR_VALUE;
|
||||
|
||||
#else
|
||||
/* Mode not implemented */
|
||||
retVal = 0x00u;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
uint16_t CRC_CalculateCRC16(const uint8_t *Buffer, uint16_t Length)
|
||||
{
|
||||
uint16_t retVal = 0u;
|
||||
uint16_t byteIndex = 0u;
|
||||
|
||||
|
||||
if(Buffer != NULL)
|
||||
{
|
||||
#if (CRC_16_MODE==RUNTTIME)
|
||||
retVal = CRC_16_INIT_VALUE;
|
||||
|
||||
/* Do calculation procedure for each byte */
|
||||
for(byteIndex = 0u; byteIndex < Length; byteIndex++)
|
||||
{
|
||||
/* XOR new byte with temp result */
|
||||
retVal ^= (Buffer[byteIndex] << (CRC_16_RESULT_WIDTH - 8u));
|
||||
|
||||
uint8_t bitIndex = 0u;
|
||||
/* Do calculation for current data */
|
||||
for(bitIndex = 0u; bitIndex < 8u; bitIndex++)
|
||||
{
|
||||
if(retVal & (1u << (CRC_16_RESULT_WIDTH - 1u)))
|
||||
{
|
||||
retVal = (retVal << 1u) ^ CRC_16_POLYNOMIAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = (retVal << 1u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* XOR result with specified value */
|
||||
retVal ^= CRC_16_XOR_VALUE;
|
||||
|
||||
#elif (CRC_16_MODE==TABLE)
|
||||
retVal = CRC_16_INIT_VALUE;
|
||||
|
||||
/* Update the CRC using the data */
|
||||
for(byteIndex = 0u; byteIndex < Length; byteIndex++)
|
||||
{
|
||||
retVal = (retVal << 8u) ^ CRC16Table[(retVal >> 8u) ^ Buffer[byteIndex]];
|
||||
}
|
||||
|
||||
/* XOR result with specified value */
|
||||
retVal ^= CRC_16_XOR_VALUE;
|
||||
#else
|
||||
/* Mode not implemented */
|
||||
retVal = 0x0000u;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
uint32_t CRC_CalculateCRC32(const uint8_t *Buffer, uint16_t Length)
|
||||
{
|
||||
uint32_t retVal = 0u;
|
||||
uint16_t byteIndex = 0u;
|
||||
|
||||
|
||||
if(Buffer != NULL)
|
||||
{
|
||||
#if (CRC_32_MODE==RUNTTIME)
|
||||
retVal = CRC_32_INIT_VALUE;
|
||||
|
||||
/* Do calculation procedure for each byte */
|
||||
for(byteIndex = 0u; byteIndex < Length; byteIndex++)
|
||||
{
|
||||
/* XOR new byte with temp result */
|
||||
retVal ^= (CRC_ReverseBitOrder8(Buffer[byteIndex]) << (CRC_32_RESULT_WIDTH - 8u));
|
||||
|
||||
uint8_t bitIndex = 0u;
|
||||
/* Do calculation for current data */
|
||||
for(bitIndex = 0u; bitIndex < 8u; bitIndex++)
|
||||
{
|
||||
if(retVal & (1u << (CRC_32_RESULT_WIDTH - 1u)))
|
||||
{
|
||||
retVal = (retVal << 1u) ^ CRC_32_POLYNOMIAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = (retVal << 1u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* XOR result with specified value */
|
||||
retVal ^= CRC_32_XOR_VALUE;
|
||||
|
||||
#elif (CRC_32_MODE==TABLE)
|
||||
uint8_t data = 0u;
|
||||
|
||||
retVal = CRC_32_INIT_VALUE;
|
||||
|
||||
for(byteIndex = 0u; byteIndex < Length; ++byteIndex)
|
||||
{
|
||||
data = CRC_ReverseBitOrder8(Buffer[byteIndex]) ^ (retVal >> (CRC_32_RESULT_WIDTH - 8u));
|
||||
retVal = CRC32Table[data] ^ (retVal << 8u);
|
||||
}
|
||||
|
||||
/* XOR result with specified value */
|
||||
retVal ^= CRC_32_XOR_VALUE;
|
||||
|
||||
#else
|
||||
/* Mode not implemented */
|
||||
retVal = 0x00000000u;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Reflect result */
|
||||
retVal = CRC_ReverseBitOrder32(retVal);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
static void CRC_CalculateCRC8Table(void)
|
||||
{
|
||||
#if (CRC_8_MODE==TABLE)
|
||||
uint16_t i = 0u, j = 0u;
|
||||
|
||||
for(i = 0u; i < 256u; ++i)
|
||||
{
|
||||
uint8_t curr = i;
|
||||
|
||||
for(j = 0u; j < 8u; ++j)
|
||||
{
|
||||
if((curr & 0x80u) != 0u)
|
||||
{
|
||||
curr = (curr << 1u) ^ CRC_8_POLYNOMIAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
curr <<= 1u;
|
||||
}
|
||||
}
|
||||
|
||||
CRC8Table[i] = curr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void CRC_CalculateCRC16Table(void)
|
||||
{
|
||||
#if (CRC_16_MODE==TABLE)
|
||||
uint16_t i = 0u, j = 0u;
|
||||
uint16_t result = 0u;
|
||||
uint16_t xor_flag = 0u;
|
||||
|
||||
for(i = 0u; i < 256u; i++)
|
||||
{
|
||||
result = i << 8u;
|
||||
|
||||
for(j = 0u; j < 8u; j++)
|
||||
{
|
||||
/* Flag for XOR if leftmost bit is set */
|
||||
xor_flag = result & 0x8000u;
|
||||
|
||||
/* Shift CRC */
|
||||
result <<= 1u;
|
||||
|
||||
/* Perform the XOR */
|
||||
if(xor_flag != 0u)
|
||||
result ^= CRC_16_POLYNOMIAL;
|
||||
}
|
||||
|
||||
CRC16Table[i] = result;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void CRC_CalculateCRC32Table(void)
|
||||
{
|
||||
#if (CRC_32_MODE==TABLE)
|
||||
uint32_t remainder = 0u;
|
||||
|
||||
for(uint32_t dividend = 0u; dividend < 256u; ++dividend)
|
||||
{
|
||||
remainder = dividend << (CRC_32_RESULT_WIDTH - 8u);
|
||||
|
||||
for(uint8_t bit = 8u; bit > 0u; --bit)
|
||||
{
|
||||
if(remainder & (1u << (CRC_32_RESULT_WIDTH - 1u)))
|
||||
{
|
||||
remainder = (remainder << 1u) ^ CRC_32_POLYNOMIAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
remainder = (remainder << 1u);
|
||||
}
|
||||
}
|
||||
|
||||
CRC32Table[dividend] = remainder;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static uint8_t CRC_ReverseBitOrder8(uint8_t value)
|
||||
{
|
||||
value = (value & 0xF0) >> 4u | (value & 0x0F) << 4u;
|
||||
value = (value & 0xCC) >> 2u | (value & 0x33) << 2u;
|
||||
value = (value & 0xAA) >> 1u | (value & 0x55) << 1u;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t CRC_ReverseBitOrder32(uint32_t value)
|
||||
{
|
||||
uint32_t reversed = 0u;
|
||||
|
||||
for(uint8_t i = 31u; value; )
|
||||
{
|
||||
reversed |= (value & 1u) << i;
|
||||
value >>= 1u;
|
||||
-- i;
|
||||
}
|
||||
|
||||
return reversed;
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
CRC.h - Simple library to calculate 8-, 16-, and 32-Bit CRC
|
||||
|
||||
Copyright (c) 2018 Patrick F.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) 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.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CRC_H_INCLUDED
|
||||
#define CRC_H_INCLUDED
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define RUNTTIME 0
|
||||
#define TABLE 1
|
||||
#define HARDWARE 2
|
||||
|
||||
|
||||
/* ---------- Defines for 8-bit SAE J1850 CRC calculation (Not reflected) ------------------------------------------------------- */
|
||||
#define CRC_8_RESULT_WIDTH 8u
|
||||
#define CRC_8_POLYNOMIAL 0x1Du
|
||||
#define CRC_8_INIT_VALUE 0xFFu
|
||||
#define CRC_8_XOR_VALUE 0xFFu
|
||||
#define CRC_8_MODE TABLE
|
||||
|
||||
/* ---------- Defines for 16-bit CCITT CRC calculation (Not reflected) ---------------------------------------------------------- */
|
||||
#define CRC_16_RESULT_WIDTH 16u
|
||||
#define CRC_16_POLYNOMIAL 0x1021u
|
||||
#define CRC_16_INIT_VALUE 0xFFFFu
|
||||
#define CRC_16_XOR_VALUE 0x0000u
|
||||
#define CRC_16_MODE RUNTTIME
|
||||
|
||||
/* ---------- Defines for 32-bit CCITT CRC calculation (Reflected) -------------------------------------------------------------- */
|
||||
#define CRC_32_RESULT_WIDTH 32u
|
||||
#define CRC_32_POLYNOMIAL 0x04C11DB7u
|
||||
#define CRC_32_INIT_VALUE 0xFFFFFFFFu
|
||||
#define CRC_32_XOR_VALUE 0xFFFFFFFFu
|
||||
#define CRC_32_MODE RUNTTIME
|
||||
|
||||
|
||||
|
||||
void CRC_Init(void);
|
||||
|
||||
/**
|
||||
* This function makes a CRC8 calculation on Length data bytes with SAEJ1850 parameters
|
||||
*
|
||||
* RETURN VALUE: 8 bit result of CRC calculation
|
||||
*/
|
||||
uint8_t CRC_CalculateCRC8(const uint8_t *Buffer, uint16_t Length);
|
||||
|
||||
/**
|
||||
* This function makes a CRC16 calculation on Length data bytes
|
||||
*
|
||||
* RETURN VALUE: 16 bit result of CRC calculation
|
||||
*/
|
||||
uint16_t CRC_CalculateCRC16(const uint8_t *Buffer, uint16_t Length);
|
||||
|
||||
/**
|
||||
* This function makes a CRC32 calculation on Length data bytes
|
||||
*
|
||||
* RETURN VALUE: 32 bit result of CRC calculation
|
||||
*/
|
||||
uint32_t CRC_CalculateCRC32(const uint8_t *Buffer, uint16_t Length);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // CRC_H_INCLUDED
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
modified 12 Aug 2013
|
||||
by Soohwan Kim (suhwan@wiznet.co.kr)
|
||||
*/
|
||||
#include "Ethernet.h"
|
||||
#include "W5500.h"
|
||||
|
||||
|
||||
IPAddress_t _dnsServerAddress = {{0, 0, 0, 0}};
|
||||
|
||||
|
||||
void Ethernet_Init(uint8_t *mac, IPAddress_t *local_ip, IPAddress_t *dns_server, IPAddress_t *gateway, IPAddress_t *subnet)
|
||||
{
|
||||
W5500_Init();
|
||||
W5500_SetMACAddress(mac);
|
||||
W5500_SetIPAddress(local_ip->IP);
|
||||
W5500_SetGatewayIp(gateway->IP);
|
||||
W5500_SetSubnetMask(subnet->IP);
|
||||
|
||||
_dnsServerAddress = *dns_server;
|
||||
}
|
||||
|
||||
|
||||
IPAddress_t Ethernet_LocalIP(void)
|
||||
{
|
||||
IPAddress_t ret;
|
||||
|
||||
W5500_GetIPAddress(ret.IP);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
IPAddress_t Ethernet_SubnetMask(void)
|
||||
{
|
||||
IPAddress_t ret;
|
||||
|
||||
W5500_GetSubnetMask(ret.IP);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
IPAddress_t Ethernet_GatewayIP(void)
|
||||
{
|
||||
IPAddress_t ret;
|
||||
|
||||
W5500_GetGatewayIp(ret.IP);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
IPAddress_t Ethernet_DnsServerIP(void)
|
||||
{
|
||||
return _dnsServerAddress;
|
||||
}
|
||||
|
||||
|
||||
uint8_t Ethernet_LinkStatus(void)
|
||||
{
|
||||
return (W5500_GetPHYCFGR() & 0x01);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
modified 12 Aug 2013
|
||||
by Soohwan Kim (suhwan@wiznet.co.kr)
|
||||
*/
|
||||
#ifndef ETHERNET_H_INLUDED
|
||||
#define ETHERNET_H_INLUDED
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include "util2.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
void Ethernet_Init(uint8_t *mac_address, IPAddress_t *local_ip, IPAddress_t *dns_server, IPAddress_t *gateway, IPAddress_t *subnet);
|
||||
|
||||
IPAddress_t Ethernet_LocalIP(void);
|
||||
IPAddress_t Ethernet_SubnetMask(void);
|
||||
IPAddress_t Ethernet_GatewayIP(void);
|
||||
IPAddress_t Ethernet_DnsServerIP(void);
|
||||
|
||||
uint8_t Ethernet_LinkStatus(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // ETHERNET_H_INLUDED
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* TcpServer.c
|
||||
*
|
||||
* Created: 24.01.2018 21:49:52
|
||||
* Author: PatrickVM
|
||||
*/
|
||||
#include "ServerTCP.h"
|
||||
#include "W5500.h"
|
||||
#include "socket.h"
|
||||
#include "System32.h"
|
||||
|
||||
|
||||
static uint8_t mSock = 0;
|
||||
static uint16_t mPort = 0;
|
||||
|
||||
uint8_t ServerTCP_Init(uint8_t sock, uint16_t port)
|
||||
{
|
||||
mSock = sock;
|
||||
mPort = port;
|
||||
|
||||
// Check if socket is available
|
||||
if(W5500_READ_SOCK_REG8(sock, REG8_SnSR) == SnSR_CLOSED)
|
||||
{
|
||||
// Set socket to TCP listen mode
|
||||
socket(sock, SnMR_TCP, port, 0);
|
||||
listen(sock);
|
||||
|
||||
// OK
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Socket occupied
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void ServerTCP_DeInit(uint8_t sock)
|
||||
{
|
||||
// Release socket
|
||||
disconnect(sock);
|
||||
|
||||
Delay_ms(5);
|
||||
|
||||
// Check if socket is released
|
||||
if(W5500_READ_SOCK_REG8(sock, REG8_SnSR) != SnSR_CLOSED)
|
||||
{
|
||||
// Force release
|
||||
close(sock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t ServerTCP_Send(uint8_t sock, uint8_t *data, uint16_t len)
|
||||
{
|
||||
// Check if socket available
|
||||
if(W5500_READ_SOCK_REG8(sock, REG8_SnSR) == SnSR_ESTABLISHED)
|
||||
{
|
||||
// Send data
|
||||
if(send(sock, data, len) <= 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// OK
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
int32_t ServerTCP_Receive(uint8_t sock, uint8_t *data, uint16_t len)
|
||||
{
|
||||
// Check if data is available
|
||||
if(W5500_GetRXReceivedSize(sock))
|
||||
{
|
||||
// Read data
|
||||
return recv(sock, data, len);
|
||||
}
|
||||
|
||||
// No data available
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
uint16_t ServerTCP_DataAvailable(uint8_t sock)
|
||||
{
|
||||
return W5500_GetRXReceivedSize(sock);
|
||||
}
|
||||
|
||||
|
||||
void ServerTCP_Update(void)
|
||||
{
|
||||
// If socket is closed, reinitalize it.
|
||||
uint8_t ret = 0;
|
||||
|
||||
ret = W5500_READ_SOCK_REG8(mSock, REG8_SnSR);
|
||||
|
||||
if(ret == SnSR_CLOSE_WAIT)
|
||||
{
|
||||
ServerTCP_DeInit(mSock);
|
||||
ServerTCP_Init(mSock, mPort);
|
||||
}
|
||||
|
||||
if(ret == SnSR_CLOSED)
|
||||
{
|
||||
ServerTCP_Init(mSock, mPort);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* TcpServer.h
|
||||
*
|
||||
* Created: 24.01.2018 21:49:39
|
||||
* Author: PatrickVM
|
||||
*/
|
||||
#ifndef TCPSERVER_H_
|
||||
#define TCPSERVER_H_
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
uint8_t ServerTCP_Init(uint8_t sock, uint16_t port);
|
||||
void ServerTCP_DeInit(uint8_t sock);
|
||||
|
||||
uint8_t ServerTCP_Send(uint8_t sock, uint8_t *data, uint16_t len);
|
||||
int32_t ServerTCP_Receive(uint8_t sock, uint8_t *data, uint16_t len);
|
||||
|
||||
uint16_t ServerTCP_DataAvailable(uint8_t sock);
|
||||
|
||||
void ServerTCP_Update(void);
|
||||
|
||||
|
||||
#endif /* TCPSERVER_H_ */
|
|
@ -0,0 +1,439 @@
|
|||
/*
|
||||
W5500.c - Driver for WIZnet W5500.
|
||||
|
||||
Copyright (c) 2018 Patrick F.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) 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.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "W5500.h"
|
||||
#include "SPI.h"
|
||||
#include "System32.h"
|
||||
|
||||
|
||||
#ifndef SPI_W5500
|
||||
#define SPI_W5500 SPI3
|
||||
#endif
|
||||
|
||||
#define RESET_BIT 7
|
||||
|
||||
|
||||
static inline void Write(uint16_t _addr, uint8_t _cb, uint8_t _data);
|
||||
static inline uint16_t WriteArray(uint16_t addr, uint8_t _cb, const uint8_t *buf, uint16_t len);
|
||||
static inline uint8_t Read(uint16_t addr, uint8_t _cb);
|
||||
static inline uint16_t ReadArray(uint16_t addr, uint8_t _cb, uint8_t *buf, uint16_t len);
|
||||
|
||||
|
||||
static inline uint8_t ReadSn(SOCKET _s, uint16_t _addr);
|
||||
static inline void WriteSn(SOCKET _s, uint16_t _addr, uint8_t _data);
|
||||
static inline uint16_t ReadSnArray(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len);
|
||||
static inline uint16_t WriteSnArray(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len);
|
||||
|
||||
|
||||
void W5500_Init(void)
|
||||
{
|
||||
Spi_Init(SPI_W5500, SPI_MODE0);
|
||||
|
||||
// Set clock to 21 Mhz (W5500 should support up to about 80 Mhz)
|
||||
Spi_SetPrescaler(SPI_W5500, SPI_PRESCALER_2);
|
||||
|
||||
GPIO_ResetBits(GPIOA, GPIO_Pin_15);
|
||||
Delay_ms(40);
|
||||
GPIO_SetBits(GPIOA, GPIO_Pin_15);
|
||||
Delay_ms(25);
|
||||
|
||||
W5500_SoftReset();
|
||||
Delay_ms(20);
|
||||
|
||||
for(uint8_t i = 0; i < MAX_SOCK_NUM; i++)
|
||||
{
|
||||
uint8_t cntl_byte = (0x0C + (i<<5));
|
||||
|
||||
Write(0x1E, cntl_byte, 4); //0x1E - Sn_RXBUF_SIZE
|
||||
Write(0x1F, cntl_byte, 2); //0x1F - Sn_TXBUF_SIZE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void W5500_SoftReset(void)
|
||||
{
|
||||
uint8_t cnt = 0;
|
||||
|
||||
// Write reset bit
|
||||
W5500_WRITE_GP_REG8(REG8_MR, 1<<RESET_BIT);
|
||||
Delay_ms(1);
|
||||
|
||||
// Wait until reset is complete or timeout
|
||||
while(cnt++ < 32)
|
||||
{
|
||||
if(W5500_READ_GP_REG8(REG8_MR) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Delay_ms(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void W5500_ReadData(SOCKET s, volatile uint16_t src, volatile uint8_t *dst, uint16_t len)
|
||||
{
|
||||
uint8_t cntl_byte = (0x18 + (s<<5));
|
||||
|
||||
ReadArray((uint16_t)src , cntl_byte, (uint8_t*)dst, len);
|
||||
}
|
||||
|
||||
|
||||
void W5500_SendDataProcessing(SOCKET s, const uint8_t *data, uint16_t len)
|
||||
{
|
||||
W5500_SendDataProcessingOffset(s, 0, data, len);
|
||||
}
|
||||
|
||||
|
||||
void W5500_SendDataProcessingOffset(SOCKET s, uint16_t data_offset, const uint8_t *data, uint16_t len)
|
||||
{
|
||||
uint16_t ptr = W5500_READ_SOCK_REG16(s, REG16_SnTX_WR);
|
||||
uint8_t cntl_byte = (0x14+(s<<5));
|
||||
|
||||
ptr += data_offset;
|
||||
WriteArray(ptr, cntl_byte, data, len);
|
||||
|
||||
ptr += len;
|
||||
W5500_WRITE_SOCK_REG16(s, REG16_SnTX_WR, ptr);
|
||||
}
|
||||
|
||||
|
||||
void W5500_RecvDataProcessing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek)
|
||||
{
|
||||
uint16_t ptr;
|
||||
ptr = W5500_READ_SOCK_REG16(s, REG16_SnRX_RD);
|
||||
|
||||
W5500_ReadData(s, ptr, data, len);
|
||||
|
||||
if(!peek)
|
||||
{
|
||||
ptr += len;
|
||||
W5500_WRITE_SOCK_REG16(s, REG16_SnRX_RD, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void W5500_GetGatewayIp(uint8_t *_addr)
|
||||
{
|
||||
W5500_READ_GP_REGN(REGN_GAR_4, _addr, 4);
|
||||
}
|
||||
|
||||
|
||||
void W5500_SetGatewayIp(uint8_t *_addr)
|
||||
{
|
||||
W5500_WRITE_GP_REGN(REGN_GAR_4, _addr, 4);
|
||||
}
|
||||
|
||||
|
||||
void W5500_GetSubnetMask(uint8_t *_addr)
|
||||
{
|
||||
W5500_READ_GP_REGN(REGN_SUBR_4, _addr, 4);
|
||||
}
|
||||
|
||||
|
||||
void W5500_SetSubnetMask(uint8_t *_addr)
|
||||
{
|
||||
W5500_WRITE_GP_REGN(REGN_SUBR_4, _addr, 4);
|
||||
}
|
||||
|
||||
|
||||
void W5500_GetMACAddress(uint8_t *_addr)
|
||||
{
|
||||
W5500_READ_GP_REGN(REGN_SHAR_6, _addr, 6);
|
||||
}
|
||||
|
||||
|
||||
void W5500_SetMACAddress(uint8_t *_addr)
|
||||
{
|
||||
W5500_WRITE_GP_REGN(REGN_SHAR_6, _addr, 6);
|
||||
}
|
||||
|
||||
|
||||
void W5500_GetIPAddress(uint8_t *_addr)
|
||||
{
|
||||
W5500_READ_GP_REGN(REGN_SIPR_4, _addr, 4);
|
||||
}
|
||||
|
||||
|
||||
void W5500_SetIPAddress(uint8_t *_addr)
|
||||
{
|
||||
W5500_WRITE_GP_REGN(REGN_SIPR_4, _addr, 4);
|
||||
}
|
||||
|
||||
|
||||
void W5500_SetRetransmissionTime(uint16_t _timeout)
|
||||
{
|
||||
W5500_WRITE_GP_REG16(REG16_RTR, _timeout);
|
||||
}
|
||||
|
||||
|
||||
void W5500_SetRetransmissionCount(uint8_t _retry)
|
||||
{
|
||||
W5500_WRITE_GP_REG8(REG8_RCR, _retry);
|
||||
}
|
||||
|
||||
|
||||
void W5500_ExecCmdSn(SOCKET s, SockCMD_e _cmd)
|
||||
{
|
||||
// Send command to socket
|
||||
W5500_WRITE_SOCK_REG8(s, REG8_SnCR, _cmd);
|
||||
|
||||
// Wait for command to complete
|
||||
while(W5500_READ_SOCK_REG8(s, REG8_SnCR));
|
||||
}
|
||||
|
||||
|
||||
uint16_t W5500_GetTXFreeSize(SOCKET s)
|
||||
{
|
||||
uint16_t val = 0, val1 = 0;
|
||||
|
||||
do
|
||||
{
|
||||
val1 = W5500_READ_SOCK_REG16(s, REG16_SnTX_FSR);
|
||||
if(val1 != 0)
|
||||
{
|
||||
val = W5500_READ_SOCK_REG16(s, REG16_SnTX_FSR);
|
||||
}
|
||||
} while(val != val1);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
uint16_t W5500_GetRXReceivedSize(SOCKET s)
|
||||
{
|
||||
uint16_t val = 0, val1 = 0;
|
||||
|
||||
do
|
||||
{
|
||||
val1 = W5500_READ_SOCK_REG16(s, REG16_SnRX_RSR);
|
||||
if(val1 != 0)
|
||||
{
|
||||
val = W5500_READ_SOCK_REG16(s, REG16_SnRX_RSR);
|
||||
}
|
||||
} while (val != val1);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
void W5500_SetPHYCFGR(uint8_t _val)
|
||||
{
|
||||
W5500_WRITE_GP_REG8(REG8_PHYCFGR, _val);
|
||||
}
|
||||
|
||||
|
||||
uint8_t W5500_GetPHYCFGR(void)
|
||||
{
|
||||
return Read(0x002E, 0x00);
|
||||
}
|
||||
|
||||
|
||||
static inline void Write(uint16_t _addr, uint8_t _cb, uint8_t _data)
|
||||
{
|
||||
Spi_ChipSelect(SPI_W5500, true);
|
||||
|
||||
Spi_WriteByte(SPI_W5500, _addr >> 8);
|
||||
Spi_WriteByte(SPI_W5500, _addr & 0xFF);
|
||||
Spi_WriteByte(SPI_W5500, _cb);
|
||||
Spi_WriteByte(SPI_W5500, _data);
|
||||
|
||||
Spi_ChipSelect(SPI_W5500, false);
|
||||
__ASM("nop");
|
||||
__ASM("nop");
|
||||
}
|
||||
|
||||
|
||||
static inline uint16_t WriteArray(uint16_t _addr, uint8_t _cb, const uint8_t *_buf, uint16_t _len)
|
||||
{
|
||||
Spi_ChipSelect(SPI_W5500, true);
|
||||
|
||||
Spi_WriteByte(SPI_W5500, _addr >> 8);
|
||||
Spi_WriteByte(SPI_W5500, _addr & 0xFF);
|
||||
Spi_WriteByte(SPI_W5500, _cb);
|
||||
|
||||
for(uint16_t i = 0; i < _len; i++)
|
||||
{
|
||||
Spi_WriteByte(SPI_W5500, _buf[i]);
|
||||
}
|
||||
|
||||
Spi_ChipSelect(SPI_W5500, false);
|
||||
__ASM("nop");
|
||||
__ASM("nop");
|
||||
|
||||
return _len;
|
||||
}
|
||||
|
||||
|
||||
static inline uint8_t Read(uint16_t _addr, uint8_t _cb)
|
||||
{
|
||||
Spi_ChipSelect(SPI_W5500, true);
|
||||
|
||||
Spi_WriteByte(SPI_W5500, _addr >> 8);
|
||||
Spi_WriteByte(SPI_W5500, _addr & 0xFF);
|
||||
Spi_WriteByte(SPI_W5500, _cb);
|
||||
|
||||
uint8_t _data = Spi_ReadByte(SPI_W5500);
|
||||
|
||||
Spi_ChipSelect(SPI_W5500, false);
|
||||
__ASM("nop");
|
||||
__ASM("nop");
|
||||
|
||||
return _data;
|
||||
}
|
||||
|
||||
|
||||
static inline uint16_t ReadArray(uint16_t _addr, uint8_t _cb, uint8_t *_buf, uint16_t _len)
|
||||
{
|
||||
Spi_ChipSelect(SPI_W5500, true);
|
||||
|
||||
Spi_WriteByte(SPI_W5500, _addr >> 8);
|
||||
Spi_WriteByte(SPI_W5500, _addr & 0xFF);
|
||||
Spi_WriteByte(SPI_W5500, _cb);
|
||||
|
||||
for(uint16_t i = 0; i < _len; i++)
|
||||
{
|
||||
_buf[i] = Spi_ReadByte(SPI_W5500);
|
||||
}
|
||||
|
||||
Spi_ChipSelect(SPI_W5500, false);
|
||||
__ASM("nop");
|
||||
__ASM("nop");
|
||||
|
||||
return _len;
|
||||
}
|
||||
|
||||
|
||||
static inline uint8_t ReadSn(SOCKET _s, uint16_t _addr)
|
||||
{
|
||||
uint8_t cntl_byte = (_s<<5) + 0x08;
|
||||
|
||||
return Read(_addr, cntl_byte);
|
||||
}
|
||||
|
||||
|
||||
static inline void WriteSn(SOCKET _s, uint16_t _addr, uint8_t _data)
|
||||
{
|
||||
uint8_t cntl_byte = (_s<<5) + 0x0C;
|
||||
|
||||
Write(_addr, cntl_byte, _data);
|
||||
}
|
||||
|
||||
|
||||
static inline uint16_t ReadSnArray(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len)
|
||||
{
|
||||
uint8_t cntl_byte = (_s<<5) + 0x08;
|
||||
|
||||
return ReadArray(_addr, cntl_byte, _buf, _len);
|
||||
}
|
||||
|
||||
|
||||
static inline uint16_t WriteSnArray(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len)
|
||||
{
|
||||
uint8_t cntl_byte = (_s<<5) + 0x0C;
|
||||
|
||||
return WriteArray(_addr, cntl_byte, _buf, _len);
|
||||
}
|
||||
|
||||
|
||||
// W5500 Registers
|
||||
// ---------------
|
||||
void W5500_WRITE_GP_REG8(uint16_t address, uint8_t _data)
|
||||
{
|
||||
Write(address, 0x04, _data);
|
||||
}
|
||||
|
||||
|
||||
uint8_t W5500_READ_GP_REG8(uint16_t address)
|
||||
{
|
||||
return Read(address, 0x00);
|
||||
}
|
||||
|
||||
|
||||
void W5500_WRITE_GP_REG16(uint16_t address, uint16_t _data)
|
||||
{
|
||||
Write(address, 0x04, _data >> 8);
|
||||
Write(address + 1, 0x04, _data & 0xFF);
|
||||
}
|
||||
|
||||
|
||||
uint16_t W5500_READ_GP_REG16(uint16_t address)
|
||||
{
|
||||
uint16_t res = Read(address, 0x00);
|
||||
res = (res << 8) + Read(address + 1, 0x00);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
uint16_t W5500_WRITE_GP_REGN(uint16_t address, uint8_t *_buff, uint16_t size)
|
||||
{
|
||||
return WriteArray(address, 0x04, _buff, size);
|
||||
}
|
||||
|
||||
|
||||
uint16_t W5500_READ_GP_REGN(uint16_t address, uint8_t *_buff, uint16_t size)
|
||||
{
|
||||
return ReadArray(address, 0x00, _buff, size);
|
||||
}
|
||||
|
||||
|
||||
// W5500 Socket registers
|
||||
// ----------------------
|
||||
|
||||
void W5500_WRITE_SOCK_REG8(SOCKET _s, uint16_t address, uint8_t _data)
|
||||
{
|
||||
WriteSn(_s, address, _data);
|
||||
}
|
||||
|
||||
|
||||
uint8_t W5500_READ_SOCK_REG8(SOCKET _s, uint16_t address)
|
||||
{
|
||||
return ReadSn(_s, address);
|
||||
}
|
||||
|
||||
|
||||
void W5500_WRITE_SOCK_REG16(SOCKET _s, uint16_t address, uint16_t _data)
|
||||
{
|
||||
WriteSn(_s, address, _data >> 8); \
|
||||
WriteSn(_s, address+1, _data & 0xFF);
|
||||
}
|
||||
|
||||
|
||||
uint16_t W5500_READ_SOCK_REG16(SOCKET _s, uint16_t address)
|
||||
{
|
||||
uint16_t res = ReadSn(_s, address);
|
||||
uint16_t res2 = ReadSn(_s, address + 1);
|
||||
|
||||
res = res << 8;
|
||||
res2 = res2 & 0xFF;
|
||||
res = res | res2;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
uint16_t W5500_WRITE_SOCK_REGN(SOCKET _s, uint16_t address, uint8_t *_buff, uint16_t size)
|
||||
{
|
||||
return WriteSnArray(_s, address, _buff, size);
|
||||
}
|
||||
|
||||
|
||||
uint16_t W5500_READ_SOCK_REGN(SOCKET _s, uint16_t address, uint8_t *_buff, uint16_t size)
|
||||
{
|
||||
return ReadSnArray(_s, address, _buff, size);
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
W5500.h - Driver for WIZnet W5500.
|
||||
|
||||
Copyright (c) 2018 Patrick F.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) 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.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef W5500_H_INCLUDED
|
||||
#define W5500_H_INCLUDED
|
||||
|
||||
|
||||
#include "util2.h"
|
||||
|
||||
|
||||
#define MAX_SOCK_NUM 8
|
||||
|
||||
|
||||
#define W5500_SSIZE 2048 // Max Tx buffer size
|
||||
#define W5500_RSIZE 2048 // Max Rx buffer size
|
||||
|
||||
|
||||
// W5500 Registers
|
||||
#define REG8_MR 0x0000 // Mode
|
||||
#define REGN_GAR_4 0x0001 // Gateway IP address
|
||||
#define REGN_SUBR_4 0x0005 // Subnet mask address
|
||||
#define REGN_SHAR_6 0x0009 // Source MAC address
|
||||
#define REGN_SIPR_4 0x000F // Source IP address
|
||||
#define REG8_IR 0x0015 // Interrupt
|
||||
#define REG8_IMR 0x0016 // Interrupt Mask
|
||||
#define REG16_RTR 0x0019 // Timeout address
|
||||
#define REG8_RCR 0x001B // Retry count
|
||||
#define REGN_UIPR_4 0x0028 // Unreachable IP address in UDP mode
|
||||
#define REG16_UPORT 0x002C // Unreachable Port address in UDP mode
|
||||
#define REG8_PHYCFGR 0x002E // PHY Configuration register, default value: 0b1011 1XXX
|
||||
|
||||
|
||||
// W5500 Socket registers
|
||||
#define REG8_SnMR 0x0000 // Mode
|
||||
#define REG8_SnCR 0x0001 // Command
|
||||
#define REG8_SnIR 0x0002 // Interrupt
|
||||
#define REG8_SnSR 0x0003 // Status
|
||||
#define REG16_SnPORT 0x0004 // Source Port
|
||||
#define REGN_SnDHAR_6 0x0006 // Destination Hardw Addr
|
||||
#define REGN_SnDIPR_4 0x000C // Destination IP Addr
|
||||
#define REG16_SnDPORT 0x0010 // Destination Port
|
||||
#define REG16_SnMSSR 0x0012 // Max Segment Size
|
||||
#define REG8_SnPROTO 0x0014 // Protocol in IP RAW Mode
|
||||
#define REG8_SnTOS 0x0015 // IP TOS
|
||||
#define REG8_SnTTL 0x0016 // IP TTL
|
||||
#define REG16_SnTX_FSR 0x0020 // TX Free Size
|
||||
#define REG16_SnTX_RD 0x0022 // TX Read Pointer
|
||||
#define REG16_SnTX_WR 0x0024 // TX Write Pointer
|
||||
#define REG16_SnRX_RSR 0x0026 // RX Free Size
|
||||
#define REG16_SnRX_RD 0x0028 // RX Read Pointer
|
||||
#define REG16_SnRX_WR 0x002A // RX Write Pointer (supported?)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SnMR_CLOSE = 0x00,
|
||||
SnMR_TCP = 0x01,
|
||||
SnMR_UDP = 0x02,
|
||||
SnMR_IPRAW = 0x03,
|
||||
SnMR_MACRAW = 0x04,
|
||||
SnMR_PPPOE = 0x05,
|
||||
SnMR_ND = 0x20,
|
||||
SnMR_MULTI = 0x80
|
||||
} SnMR_e;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Sock_OPEN = 0x01,
|
||||
Sock_LISTEN = 0x02,
|
||||
Sock_CONNECT = 0x04,
|
||||
Sock_DISCON = 0x08,
|
||||
Sock_CLOSE = 0x10,
|
||||
Sock_SEND = 0x20,
|
||||
Sock_SEND_MAC = 0x21,
|
||||
Sock_SEND_KEEP = 0x22,
|
||||
Sock_RECV = 0x40
|
||||
} SockCMD_e;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SnIR_SEND_OK = 0x10,
|
||||
SnIR_TIMEOUT = 0x08,
|
||||
SnIR_RECV = 0x04,
|
||||
SnIR_DISCON = 0x02,
|
||||
SnIR_CON = 0x01
|
||||
} SnIR_e;
|
||||
|
||||
|
||||
typedef enum SnSR
|
||||
{
|
||||
SnSR_CLOSED = 0x00,
|
||||
SnSR_INIT = 0x13,
|
||||
SnSR_LISTEN = 0x14,
|
||||
SnSR_SYNSENT = 0x15,
|
||||
SnSR_SYNRECV = 0x16,
|
||||
SnSR_ESTABLISHED = 0x17,
|
||||
SnSR_FIN_WAIT = 0x18,
|
||||
SnSR_CLOSING = 0x1A,
|
||||
SnSR_TIME_WAIT = 0x1B,
|
||||
SnSR_CLOSE_WAIT = 0x1C,
|
||||
SnSR_LAST_ACK = 0x1D,
|
||||
SnSR_UDP = 0x22,
|
||||
SnSR_IPRAW = 0x32,
|
||||
SnSR_MACRAW = 0x42,
|
||||
SnSR_PPPOE = 0x5F
|
||||
} SnSR_e;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IPPROTO_IP = 0,
|
||||
IPPROTO_ICMP = 1,
|
||||
IPPROTO_IGMP = 2,
|
||||
IPPROTO_GGP = 3,
|
||||
IPPROTO_TCP = 6,
|
||||
IPPROTO_PUP = 12,
|
||||
IPPROTO_UDP = 17,
|
||||
IPPROTO_IDP = 22,
|
||||
IPPROTO_ND = 77,
|
||||
IPPROTO_RAW = 255,
|
||||
} IPPROTO_e;
|
||||
|
||||
|
||||
|
||||
void W5500_Init(void);
|
||||
|
||||
void W5500_SoftReset(void);
|
||||
|
||||
/**
|
||||
* @brief This function is being used for copy the data form Receive buffer of the chip to application buffer.
|
||||
*
|
||||
* It calculate the actual physical address where one has to read
|
||||
* the data from Receive buffer. Here also take care of the condition while it exceed
|
||||
* the Rx memory uper-bound of socket.
|
||||
*/
|
||||
void W5500_ReadData(SOCKET s, volatile uint16_t src, volatile uint8_t * dst, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief This function is being called by send() and sendto() function also.
|
||||
*
|
||||
* This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
|
||||
* register. User should read upper byte first and lower byte later to get proper value.
|
||||
*/
|
||||
void W5500_SendDataProcessing(SOCKET s, const uint8_t *data, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief A copy of send_data_processing that uses the provided ptr for the
|
||||
* write offset. Only needed for the "streaming" UDP API, where
|
||||
* a single UDP packet is built up over a number of calls to
|
||||
* send_data_processing_ptr, because TX_WR doesn't seem to get updated
|
||||
* correctly in those scenarios
|
||||
* @param ptr value to use in place of TX_WR. If 0, then the value is read
|
||||
* in from TX_WR
|
||||
* @return New value for ptr, to be used in the next call
|
||||
*/
|
||||
void W5500_SendDataProcessingOffset(SOCKET s, uint16_t data_offset, const uint8_t *data, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief This function is being called by recv() also.
|
||||
*
|
||||
* This function read the Rx read pointer register
|
||||
* and after copy the data from receive buffer update the Rx write pointer register.
|
||||
* User should read upper byte first and lower byte later to get proper value.
|
||||
*/
|
||||
void W5500_RecvDataProcessing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek);
|
||||
|
||||
void W5500_SetGatewayIp(uint8_t *_addr);
|
||||
void W5500_GetGatewayIp(uint8_t *_addr);
|
||||
|
||||
void W5500_SetSubnetMask(uint8_t *_addr);
|
||||
void W5500_GetSubnetMask(uint8_t *_addr);
|
||||
|
||||
void W5500_SetMACAddress(uint8_t *_addr);
|
||||
void W5500_GetMACAddress(uint8_t *_addr);
|
||||
|
||||
void W5500_SetIPAddress(uint8_t *_addr);
|
||||
void W5500_GetIPAddress(uint8_t *_addr);
|
||||
|
||||
void W5500_SetRetransmissionTime(uint16_t timeout);
|
||||
void W5500_SetRetransmissionCount(uint8_t _retry);
|
||||
|
||||
void W5500_ExecCmdSn(SOCKET s, SockCMD_e _cmd);
|
||||
|
||||
uint16_t W5500_GetTXFreeSize(SOCKET s);
|
||||
uint16_t W5500_GetRXReceivedSize(SOCKET s);
|
||||
|
||||
void W5500_SetPHYCFGR(uint8_t _val);
|
||||
uint8_t W5500_GetPHYCFGR(void);
|
||||
|
||||
|
||||
// W5500 Registers
|
||||
// ---------------
|
||||
void W5500_WRITE_GP_REG8(uint16_t address, uint8_t _data);
|
||||
uint8_t W5500_READ_GP_REG8(uint16_t address);
|
||||
void W5500_WRITE_GP_REG16(uint16_t address, uint16_t _data);
|
||||
uint16_t W5500_READ_GP_REG16(uint16_t address);
|
||||
uint16_t W5500_WRITE_GP_REGN(uint16_t address, uint8_t *_buff, uint16_t size);
|
||||
uint16_t W5500_READ_GP_REGN(uint16_t address, uint8_t *_buff, uint16_t size);
|
||||
|
||||
|
||||
// W5500 Socket registers
|
||||
// ----------------------
|
||||
void W5500_WRITE_SOCK_REG8(SOCKET _s, uint16_t address, uint8_t _data);
|
||||
uint8_t W5500_READ_SOCK_REG8(SOCKET _s, uint16_t address);
|
||||
void W5500_WRITE_SOCK_REG16(SOCKET _s, uint16_t address, uint16_t _data);
|
||||
uint16_t W5500_READ_SOCK_REG16(SOCKET _s, uint16_t address);
|
||||
uint16_t W5500_WRITE_SOCK_REGN(SOCKET _s, uint16_t address, uint8_t *_buff, uint16_t size);
|
||||
uint16_t W5500_READ_SOCK_REGN(SOCKET _s, uint16_t address, uint8_t *_buff, uint16_t size);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,507 @@
|
|||
/*
|
||||
socket.c - SOCKET APIs like as berkeley socket api.
|
||||
|
||||
Copyright (c) 2018 Patrick F.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) 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.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "W5500.h"
|
||||
#include "socket.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief This Socket function initialize the channel in perticular mode, and set the port and wait for W5100 done it.
|
||||
* @return 1 for success else 0.
|
||||
*/
|
||||
int8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)
|
||||
{
|
||||
if(s < MAX_SOCK_NUM)
|
||||
{
|
||||
if((protocol == SnMR_TCP) || (protocol == SnMR_UDP) || (protocol == SnMR_IPRAW) || (protocol == SnMR_MACRAW) || (protocol == SnMR_PPPOE))
|
||||
{
|
||||
close(s);
|
||||
|
||||
W5500_WRITE_SOCK_REG8(s, REG8_SnMR, protocol | flag);
|
||||
|
||||
if(port)
|
||||
{
|
||||
W5500_WRITE_SOCK_REG16(s, REG16_SnPORT, port);
|
||||
|
||||
W5500_ExecCmdSn(s, Sock_OPEN);
|
||||
|
||||
return SOCK_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SOCKERR_PORTZERO;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return SOCKERR_SOCKMODE;
|
||||
}
|
||||
}
|
||||
|
||||
return SOCKERR_SOCKNUM;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function close the socket and parameter is "s" which represent the socket number
|
||||
*/
|
||||
int8_t close(SOCKET s)
|
||||
{
|
||||
if(s < MAX_SOCK_NUM)
|
||||
{
|
||||
W5500_ExecCmdSn(s, Sock_CLOSE);
|
||||
// Clear interrupts
|
||||
W5500_WRITE_SOCK_REG8(s, REG8_SnIR, 0xFF);
|
||||
}
|
||||
|
||||
return SOCKERR_SOCKNUM;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function established the connection for the channel in passive (server) mode. This function waits for the request from the peer.
|
||||
* @return 1 for success else 0.
|
||||
*/
|
||||
int8_t listen(SOCKET s)
|
||||
{
|
||||
if(s < MAX_SOCK_NUM)
|
||||
{
|
||||
if(W5500_READ_SOCK_REG8(s, REG8_SnSR) != (uint8_t)SnSR_INIT)
|
||||
{
|
||||
return SOCKERR_SOCKINIT;
|
||||
}
|
||||
|
||||
W5500_ExecCmdSn(s, Sock_LISTEN);
|
||||
|
||||
return SOCK_OK;
|
||||
}
|
||||
|
||||
return SOCKERR_SOCKNUM;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function established the connection for the channel in Active (client) mode.
|
||||
* This function waits for the untill the connection is established.
|
||||
*
|
||||
* @return 1 for success else 0.
|
||||
*/
|
||||
int8_t connect(SOCKET s, uint8_t * addr, uint16_t port)
|
||||
{
|
||||
if(s < MAX_SOCK_NUM)
|
||||
{
|
||||
if(((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
|
||||
((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
|
||||
(port == 0x00))
|
||||
{
|
||||
return SOCKERR_IPINVALID;
|
||||
}
|
||||
|
||||
// Set destination IP
|
||||
W5500_WRITE_SOCK_REGN(s, REGN_SnDIPR_4, addr, 4);
|
||||
W5500_WRITE_SOCK_REG16(s, REG16_SnDPORT, port);
|
||||
W5500_ExecCmdSn(s, Sock_CONNECT);
|
||||
|
||||
return SOCK_OK;
|
||||
}
|
||||
|
||||
return SOCKERR_SOCKNUM;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function used for disconnect the socket and parameter is "s" which represent the socket number
|
||||
* @return 1 for success else 0.
|
||||
*/
|
||||
int8_t disconnect(SOCKET s)
|
||||
{
|
||||
if(s < MAX_SOCK_NUM)
|
||||
{
|
||||
W5500_ExecCmdSn(s, Sock_DISCON);
|
||||
|
||||
return SOCK_OK;
|
||||
}
|
||||
|
||||
return SOCKERR_SOCKNUM;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function used to send the data in TCP mode
|
||||
* @return 1 for success else 0.
|
||||
*/
|
||||
int32_t send(SOCKET s, const uint8_t * buf, uint16_t len)
|
||||
{
|
||||
uint8_t status = 0;
|
||||
uint16_t ret = 0;
|
||||
uint16_t freesize = 0;
|
||||
|
||||
|
||||
if(len > W5500_SSIZE)
|
||||
ret = W5500_SSIZE; // check size not to exceed MAX size.
|
||||
else
|
||||
ret = len;
|
||||
|
||||
if(s < MAX_SOCK_NUM)
|
||||
{
|
||||
// if freebuf is available, start.
|
||||
do
|
||||
{
|
||||
freesize = W5500_GetTXFreeSize(s);
|
||||
|
||||
status = W5500_READ_SOCK_REG8(s, REG8_SnSR);
|
||||
if((status != SnSR_ESTABLISHED) && (status != SnSR_CLOSE_WAIT))
|
||||
{
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
} while(freesize < ret);
|
||||
|
||||
// copy data
|
||||
W5500_SendDataProcessing(s, (uint8_t *)buf, ret);
|
||||
W5500_ExecCmdSn(s, Sock_SEND);
|
||||
|
||||
/* +2008.01 bj */
|
||||
while((W5500_READ_SOCK_REG8(s, REG8_SnIR) & SnIR_SEND_OK) != SnIR_SEND_OK)
|
||||
{
|
||||
/* m2008.01 [bj] : reduce code */
|
||||
if(W5500_READ_SOCK_REG8(s, REG8_SnSR) == SnSR_CLOSED)
|
||||
{
|
||||
close(s);
|
||||
|
||||
return SOCKERR_SOCKCLOSED;
|
||||
}
|
||||
}
|
||||
|
||||
/* +2008.01 bj */
|
||||
W5500_WRITE_SOCK_REG8(s, REG8_SnIR, SnIR_SEND_OK);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is an application I/F function which is used to receive the data in TCP mode.
|
||||
* It continues to wait for data as much as the application wants to receive.
|
||||
*
|
||||
* @return received data size for success else -1.
|
||||
*/
|
||||
int32_t recv(SOCKET s, uint8_t *buf, int16_t len)
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
|
||||
|
||||
if(s < MAX_SOCK_NUM)
|
||||
{
|
||||
// Check how much data is available
|
||||
ret = W5500_GetRXReceivedSize(s);
|
||||
if(ret == 0)
|
||||
{
|
||||
// No data available.
|
||||
uint8_t status = W5500_READ_SOCK_REG8(s, REG8_SnSR);
|
||||
if(status == SnSR_LISTEN || status == SnSR_CLOSED || status == SnSR_CLOSE_WAIT)
|
||||
{
|
||||
// The remote end has closed its side of the connection, so this is the eof state
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The connection is still up, but there's no data waiting to be read
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
else if(ret > len)
|
||||
{
|
||||
ret = len;
|
||||
}
|
||||
|
||||
if(ret > 0)
|
||||
{
|
||||
W5500_RecvDataProcessing(s, buf, ret, 0);
|
||||
W5500_ExecCmdSn(s, Sock_RECV);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return SOCKERR_SOCKNUM;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns the first byte in the receive queue (no checking)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
uint16_t peek(SOCKET s, uint8_t *buf)
|
||||
{
|
||||
if(s < MAX_SOCK_NUM)
|
||||
{
|
||||
W5500_RecvDataProcessing(s, buf, 1, 1);
|
||||
|
||||
return SOCK_OK;
|
||||
}
|
||||
|
||||
return SOCKERR_SOCKNUM;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is an application I/F function which is used to send the data for other then TCP mode.
|
||||
* Unlike TCP transmission, The peer's destination address and the port is needed.
|
||||
*
|
||||
* @return This function return send data size for success else -1.
|
||||
*/
|
||||
int32_t sendto(SOCKET s, const uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t port)
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
|
||||
|
||||
if(len > W5500_SSIZE)
|
||||
ret = W5500_SSIZE; // check size not to exceed MAX size.
|
||||
else
|
||||
ret = len;
|
||||
|
||||
if(s < MAX_SOCK_NUM)
|
||||
{
|
||||
if(((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) || ((port == 0x00)) || (ret == 0))
|
||||
{
|
||||
/* +2008.01 [bj] : added return value */
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
W5500_WRITE_SOCK_REGN(s, REGN_SnDIPR_4, addr, 4);
|
||||
W5500_WRITE_SOCK_REG16(s, REG16_SnDPORT, port);
|
||||
|
||||
// copy data
|
||||
W5500_SendDataProcessing(s, (uint8_t *)buf, ret);
|
||||
W5500_ExecCmdSn(s, Sock_SEND);
|
||||
|
||||
/* +2008.01 bj */
|
||||
while((W5500_READ_SOCK_REG8(s, REG8_SnIR) & SnIR_SEND_OK) != SnIR_SEND_OK)
|
||||
{
|
||||
if(W5500_READ_SOCK_REG8(s, REG8_SnIR) & SnIR_TIMEOUT)
|
||||
{
|
||||
/* +2008.01 [bj]: clear interrupt */
|
||||
W5500_WRITE_SOCK_REG8(s, REG8_SnIR, (SnIR_SEND_OK | SnIR_TIMEOUT)); /* clear SEND_OK & TIMEOUT */
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* +2008.01 bj */
|
||||
W5500_WRITE_SOCK_REG8(s, REG8_SnIR, SnIR_SEND_OK);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is an application I/F function which is used to receive the data in other then
|
||||
* TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well.
|
||||
*
|
||||
* @return This function return received data size for success else -1.
|
||||
*/
|
||||
int32_t recvfrom(SOCKET s, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t *port)
|
||||
{
|
||||
uint8_t head[8];
|
||||
uint16_t data_len = 0;
|
||||
uint16_t ptr = 0;
|
||||
|
||||
if((s < MAX_SOCK_NUM) && (len > 0))
|
||||
{
|
||||
ptr = W5500_READ_SOCK_REG16(s, REG16_SnRX_RD);
|
||||
|
||||
switch(W5500_READ_SOCK_REG8(s, REG8_SnMR) & 0x07)
|
||||
{
|
||||
case SnMR_UDP :
|
||||
W5500_ReadData(s, ptr, head, 0x08);
|
||||
ptr += 8;
|
||||
// read peer's IP address, port number.
|
||||
addr[0] = head[0];
|
||||
addr[1] = head[1];
|
||||
addr[2] = head[2];
|
||||
addr[3] = head[3];
|
||||
*port = head[4];
|
||||
*port = (*port << 8) + head[5];
|
||||
data_len = head[6];
|
||||
data_len = (data_len << 8) + head[7];
|
||||
|
||||
W5500_ReadData(s, ptr, buf, data_len); // data copy.
|
||||
ptr += data_len;
|
||||
|
||||
W5500_WRITE_SOCK_REG16(s, REG16_SnRX_RD, ptr);
|
||||
break;
|
||||
|
||||
case SnMR_IPRAW :
|
||||
W5500_ReadData(s, ptr, head, 0x06);
|
||||
ptr += 6;
|
||||
|
||||
addr[0] = head[0];
|
||||
addr[1] = head[1];
|
||||
addr[2] = head[2];
|
||||
addr[3] = head[3];
|
||||
data_len = head[4];
|
||||
data_len = (data_len << 8) + head[5];
|
||||
|
||||
W5500_ReadData(s, ptr, buf, data_len); // data copy.
|
||||
ptr += data_len;
|
||||
|
||||
W5500_WRITE_SOCK_REG16(s, REG16_SnRX_RD, ptr);
|
||||
break;
|
||||
|
||||
case SnMR_MACRAW:
|
||||
W5500_ReadData(s, ptr, head, 2);
|
||||
ptr+=2;
|
||||
data_len = head[0];
|
||||
data_len = (data_len<<8) + head[1] - 2;
|
||||
|
||||
W5500_ReadData(s, ptr, buf, data_len);
|
||||
ptr += data_len;
|
||||
W5500_WRITE_SOCK_REG16(s, REG16_SnRX_RD, ptr);
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
W5500_ExecCmdSn(s, Sock_RECV);
|
||||
}
|
||||
|
||||
return data_len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Wait for buffered transmission to complete.
|
||||
*/
|
||||
void flush(SOCKET s)
|
||||
{
|
||||
if(s < MAX_SOCK_NUM)
|
||||
{
|
||||
// TODO
|
||||
(void)s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len)
|
||||
{
|
||||
//uint8_t status = 0;
|
||||
uint16_t ret = 0;
|
||||
|
||||
|
||||
if(len > W5500_SSIZE)
|
||||
ret = W5500_SSIZE; // check size not to exceed MAX size.
|
||||
else
|
||||
ret = len;
|
||||
|
||||
if(ret == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
if(s < MAX_SOCK_NUM)
|
||||
{
|
||||
W5500_SendDataProcessing(s, (uint8_t *)buf, ret);
|
||||
W5500_ExecCmdSn(s, Sock_SEND);
|
||||
|
||||
while((W5500_READ_SOCK_REG8(s, REG8_SnIR) & SnIR_SEND_OK) != SnIR_SEND_OK)
|
||||
{
|
||||
//status = W5100_READ_SOCK_REG8(s, REG8_SnSR);
|
||||
W5500_READ_SOCK_REG8(s, REG8_SnSR);
|
||||
|
||||
if(W5500_READ_SOCK_REG8(s, REG8_SnIR) & SnIR_TIMEOUT)
|
||||
{
|
||||
/* in case of igmp, if send fails, then socket closed */
|
||||
/* if you want change, remove this code. */
|
||||
close(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
W5500_WRITE_SOCK_REG8(s, REG8_SnIR, SnIR_SEND_OK);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint16_t bufferData(SOCKET s, uint16_t offset, const uint8_t* buf, uint16_t len)
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
|
||||
|
||||
if(len > W5500_GetTXFreeSize(s))
|
||||
{
|
||||
ret = W5500_GetTXFreeSize(s); // check size not to exceed MAX size.
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = len;
|
||||
}
|
||||
|
||||
W5500_SendDataProcessingOffset(s, offset, buf, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int startUDP(SOCKET s, uint8_t* addr, uint16_t port)
|
||||
{
|
||||
if(((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) || ((port == 0x00)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
W5500_WRITE_SOCK_REGN(s, REGN_SnDIPR_4, addr, 4);
|
||||
W5500_WRITE_SOCK_REG16(s, REG16_SnDPORT, port);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int sendUDP(SOCKET s)
|
||||
{
|
||||
W5500_ExecCmdSn(s, Sock_SEND);
|
||||
|
||||
/* +2008.01 bj */
|
||||
while((W5500_READ_SOCK_REG8(s, REG8_SnIR) & SnIR_SEND_OK) != SnIR_SEND_OK )
|
||||
{
|
||||
if(W5500_READ_SOCK_REG8(s, REG8_SnIR) & SnIR_TIMEOUT)
|
||||
{
|
||||
/* +2008.01 [bj]: clear interrupt */
|
||||
W5500_WRITE_SOCK_REG8(s, REG8_SnIR, (SnIR_SEND_OK | SnIR_TIMEOUT));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* +2008.01 bj */
|
||||
W5500_WRITE_SOCK_REG8(s, REG8_SnIR, SnIR_SEND_OK);
|
||||
|
||||
/* Sent ok */
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
socket.c - SOCKET APIs like as berkeley socket api.
|
||||
|
||||
Copyright (c) 2018 Patrick F.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) 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.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _SOCKET_H_
|
||||
#define _SOCKET_H_
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include "util.h"
|
||||
|
||||
|
||||
#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
|
||||
#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 argrument.
|
||||
#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.
|
||||
|
||||
|
||||
#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.
|
||||
#define PACK_REMAINED 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received.
|
||||
#define PACK_COMPLETED 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet.
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Opens a socket(TCP or UDP or IP_RAW mode)
|
||||
int8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag);
|
||||
// Close socket
|
||||
int8_t close(SOCKET s);
|
||||
|
||||
// Establish TCP connection (Active connection)
|
||||
int8_t connect(SOCKET s, uint8_t * addr, uint16_t port);
|
||||
// disconnect the connection
|
||||
int8_t disconnect(SOCKET s);
|
||||
|
||||
// Establish TCP connection (Passive connection)
|
||||
int8_t listen(SOCKET s);
|
||||
|
||||
// Send data (TCP)
|
||||
int32_t send(SOCKET s, const uint8_t * buf, uint16_t len);
|
||||
// Receive data (TCP)
|
||||
int32_t recv(SOCKET s, uint8_t * buf, int16_t len);
|
||||
|
||||
uint16_t peek(SOCKET s, uint8_t *buf);
|
||||
|
||||
// Send data (UDP/IP RAW)
|
||||
int32_t sendto(SOCKET s, const uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port);
|
||||
// Receive data (UDP/IP RAW)
|
||||
int32_t recvfrom(SOCKET s, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port);
|
||||
|
||||
// Wait for transmission to complete
|
||||
void flush(SOCKET s);
|
||||
|
||||
|
||||
|
||||
uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len);
|
||||
|
||||
// Functions to allow buffered UDP send (i.e. where the UDP datagram is built up over a
|
||||
// number of calls before being sent
|
||||
/*
|
||||
@brief This function sets up a UDP datagram, the data for which will be provided by one
|
||||
or more calls to bufferData and then finally sent with sendUDP.
|
||||
@return 1 if the datagram was successfully set up, or 0 if there was an error
|
||||
*/
|
||||
int startUDP(SOCKET s, uint8_t* addr, uint16_t port);
|
||||
/*
|
||||
@brief This function copies up to len bytes of data from buf into a UDP datagram to be
|
||||
sent later by sendUDP. Allows datagrams to be built up from a series of bufferData calls.
|
||||
@return Number of bytes successfully buffered
|
||||
*/
|
||||
uint16_t bufferData(SOCKET s, uint16_t offset, const uint8_t* buf, uint16_t len);
|
||||
/*
|
||||
@brief Send a UDP datagram built up from a sequence of startUDP followed by one or more
|
||||
calls to bufferData.
|
||||
@return 1 if the datagram was successfully sent, or 0 if there was an error
|
||||
*/
|
||||
int sendUDP(SOCKET s);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _SOCKET_H_ */
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef UTIL2_H
|
||||
#define UTIL2_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#define htons(x) ((uint16_t)(((x)<<8) | (((x)>>8)&0xFF)))
|
||||
#define ntohs(x) htons(x)
|
||||
|
||||
#define htonl(x) (((x)<<24 & 0xFF000000UL) | ((x)<< 8 & 0x00FF0000UL) | ((x)>> 8 & 0x0000FF00UL) | ((x)>>24 & 0x000000FFUL))
|
||||
#define ntohl(x) htonl(x)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef uint8_t SOCKET;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t IP[4];
|
||||
} IPAddress_t;
|
||||
|
||||
static const IPAddress_t INADDR_NONE = {0};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
ComIf.c - Communication Interface
|
||||
|
||||
Copyright (c) 2018-2019 Patrick F.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) 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.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "ComIf.h"
|
||||
#include "ServerTCP.h"
|
||||
#include "Platform.h"
|
||||
#include "Print.h"
|
||||
#include "Usart.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// Buffer size of interface
|
||||
#ifndef COMIF_BUFFER_SIZE
|
||||
#define COMIF_BUFFER_SIZE 512
|
||||
#endif
|
||||
|
||||
#define MAX_READ_SIZE 64
|
||||
|
||||
|
||||
static inline uint16_t BufferFreeBytes(void);
|
||||
static inline void BufferWriteByte(uint8_t data);
|
||||
static inline uint8_t BufferReadByte(void);
|
||||
|
||||
|
||||
static uint8_t RxBuffer[COMIF_BUFFER_SIZE] = {0};
|
||||
static uint16_t Head = 0, Tail = 0, Size = 0;
|
||||
|
||||
static uint8_t Socket = 0;
|
||||
static uint8_t Interface = IF_USB;
|
||||
|
||||
|
||||
void ComIf_Init(uint8_t interface, uint8_t sock)
|
||||
{
|
||||
Head = 0, Tail = 0, Size = 0;
|
||||
memset(RxBuffer, 0, COMIF_BUFFER_SIZE);
|
||||
Socket = sock;
|
||||
Interface = interface;
|
||||
}
|
||||
|
||||
|
||||
void ComIf_DeInit(void)
|
||||
{
|
||||
ComIf_Init(Interface, 0);
|
||||
}
|
||||
|
||||
|
||||
uint8_t ComIf_Send(uint8_t *data, uint16_t len)
|
||||
{
|
||||
if(Interface == IF_ETH)
|
||||
{
|
||||
return ServerTCP_Send(Socket, data, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
Usart_Write(STDOUT, false, (char*)data, len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint16_t ComIf_Receive(uint8_t *data, uint16_t len)
|
||||
{
|
||||
// Check if data available
|
||||
uint16_t rec = ComIf_DataAvailable();
|
||||
if(rec)
|
||||
{
|
||||
if(len > rec)
|
||||
{
|
||||
len = rec;
|
||||
}
|
||||
|
||||
for(uint16_t i = 0; i < len; i++)
|
||||
{
|
||||
data[i] = BufferReadByte();
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
// No data available
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint16_t ComIf_DataAvailable(void)
|
||||
{
|
||||
return (COMIF_BUFFER_SIZE - BufferFreeBytes());
|
||||
}
|
||||
|
||||
|
||||
void ComIf_Update(void)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
|
||||
if(Interface == IF_ETH)
|
||||
{
|
||||
ret = ServerTCP_DataAvailable(Socket);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assume, that there is always data available on serial
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if(ret && (MAX_READ_SIZE <= BufferFreeBytes()))
|
||||
{
|
||||
uint8_t buf[MAX_READ_SIZE];
|
||||
|
||||
// Read max 64 bytes
|
||||
if(ret > MAX_READ_SIZE)
|
||||
{
|
||||
ret = MAX_READ_SIZE;
|
||||
}
|
||||
|
||||
if(Interface == IF_ETH)
|
||||
{
|
||||
// Read max 64 bytes from TCP socket and write it into buffer
|
||||
uint8_t read = ServerTCP_Receive(Socket, buf, ret);
|
||||
|
||||
for(uint8_t i = 0; i < read; i++)
|
||||
{
|
||||
BufferWriteByte(buf[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read max 64 bytes from usart buffer
|
||||
for(uint16_t read = 0; read < MAX_READ_SIZE; read++)
|
||||
{
|
||||
char c;
|
||||
if(Getc(&c) == 0)
|
||||
{
|
||||
BufferWriteByte((uint8_t)c);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline void BufferWriteByte(uint8_t data)
|
||||
{
|
||||
if(Size > (COMIF_BUFFER_SIZE-1))
|
||||
{
|
||||
// Queue full
|
||||
return;
|
||||
}
|
||||
|
||||
RxBuffer[Head] = data;
|
||||
Head = (Head + 1) % COMIF_BUFFER_SIZE;
|
||||
Size++;
|
||||
}
|
||||
|
||||
|
||||
static inline uint8_t BufferReadByte(void)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
|
||||
if(Size)
|
||||
{
|
||||
ret = RxBuffer[Tail];
|
||||
Tail = (Tail + 1) % COMIF_BUFFER_SIZE;
|
||||
Size--;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static inline uint16_t BufferFreeBytes(void)
|
||||
{
|
||||
return (COMIF_BUFFER_SIZE - Size);
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
ComIf.h - Communication Interface
|
||||
|
||||
Copyright (c) 2018-2019 Patrick F.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) 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.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef COMMUNICATIONINTERFACE_H_INCLUDED
|
||||
#define COMMUNICATIONINTERFACE_H_INCLUDED
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#define IF_USB 0
|
||||
#define IF_ETH 1
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/** \brief Initialize communication interface.
|
||||
*
|
||||
* \param sock Socket number of TCP server.
|
||||
* \return None.
|
||||
*
|
||||
*/
|
||||
void ComIf_Init(uint8_t interface, uint8_t sock);
|
||||
|
||||
/** \brief Deinitalize communication interface.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
*/
|
||||
void ComIf_DeInit(void);
|
||||
|
||||
|
||||
/** \brief Transmit data.
|
||||
*
|
||||
* \param data Data array to transmit.
|
||||
* \param len Length of data array in bytes.
|
||||
* \return 0 if success.
|
||||
*
|
||||
*/
|
||||
uint8_t ComIf_Send(uint8_t *data, uint16_t len);
|
||||
|
||||
/** \brief Get data from communication interface.
|
||||
*
|
||||
* \param data Pointer where to store the data.
|
||||
* \param len Max number of bytes to read.
|
||||
* \return Number of read bytes. 0 if no bytes were read.
|
||||
*
|
||||
*/
|
||||
uint16_t ComIf_Receive(uint8_t *data, uint16_t len);
|
||||
|
||||
/** \brief Return if data is available.
|
||||
*
|
||||
* \return Number of bytes available.
|
||||
*
|
||||
*/
|
||||
uint16_t ComIf_DataAvailable(void);
|
||||
|
||||
/** \brief Cyclic update function. Gets data from hardware interface and stores it in internal buffer. Should be called periodically.
|
||||
*
|
||||
* \return None.
|
||||
*
|
||||
*/
|
||||
void ComIf_Update(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // COMMUNICATIONINTERFACE_H_INCLUDED
|
|
@ -0,0 +1,292 @@
|
|||
/*
|
||||
GrIP.c - GRBL over IP
|
||||
|
||||
Copyright (c) 2018-2019 Patrick F.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) 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.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "GrIP.h"
|
||||
#include "CRC.h"
|
||||
#include "util2.h"
|
||||
#include "ComIf.h"
|
||||
#include "Print.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// GrIP states
|
||||
#define GRIP_IDLE 0
|
||||
#define GRIP_RX_HEADER 1
|
||||
#define GRIP_RX_DATA 2
|
||||
|
||||
// Magic byte - Marks start of transmission
|
||||
#define MAGIC 0x55
|
||||
|
||||
// Size of header packet
|
||||
#define GRIP_HEADER_SIZE (sizeof(GrIP_PacketHeader_t))
|
||||
|
||||
|
||||
static uint8_t CheckHeader(GrIP_PacketHeader_t *paket);
|
||||
|
||||
|
||||
static GrIP_PacketHeader_t TX_Header;
|
||||
|
||||
// Transmit Buffer
|
||||
static uint8_t TX_Buffer[GRIP_BUFFER_SIZE + GRIP_HEADER_SIZE];
|
||||
// Receive Data Array
|
||||
static RX_Packet_t RX_Buff[GRIP_RX_NUM] = {0};
|
||||
|
||||
static uint8_t GrIP_Status = GRIP_IDLE;
|
||||
static uint8_t GrIP_Response = RESPONSE_OK;
|
||||
static uint8_t GrIP_idx = 0;
|
||||
|
||||
|
||||
void GrIP_Init(void)
|
||||
{
|
||||
// Initialize to default values
|
||||
GrIP_Status = GRIP_IDLE;
|
||||
GrIP_idx = 0;
|
||||
|
||||
memset(&TX_Header, 0, GRIP_HEADER_SIZE);
|
||||
|
||||
memset(TX_Buffer, 0, GRIP_BUFFER_SIZE + GRIP_HEADER_SIZE);
|
||||
memset(RX_Buff, 0, sizeof(RX_Buff));
|
||||
|
||||
// Init generic interface
|
||||
ComIf_Init(IF_ETH, 0);
|
||||
// Init CRC module
|
||||
CRC_Init();
|
||||
}
|
||||
|
||||
|
||||
uint8_t GrIP_Transmit(uint8_t MsgType, uint8_t ReturnCode, Pdu_t *data)
|
||||
{
|
||||
// Prepare header
|
||||
TX_Header.Version = GRIP_VERSION;
|
||||
TX_Header.MsgType = MsgType;
|
||||
TX_Header.ReturnCode = ReturnCode;
|
||||
|
||||
if(data)
|
||||
{
|
||||
// Convert length to network order
|
||||
TX_Header.Length = htons(data->Length);
|
||||
|
||||
// Check if data fits into transmit buffer
|
||||
if(data->Length > GRIP_BUFFER_SIZE)
|
||||
{
|
||||
return RET_NOK;
|
||||
}
|
||||
else if(data->Length > 0)
|
||||
{
|
||||
// Calculate CRC of data
|
||||
TX_Header.CRC8 = CRC_CalculateCRC8(data->Data, data->Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No data, no CRC
|
||||
TX_Header.CRC8 = 0;
|
||||
}
|
||||
|
||||
// Prepare transmit buffer
|
||||
TX_Buffer[0] = MAGIC;
|
||||
memcpy(&TX_Buffer[1], &TX_Header, GRIP_HEADER_SIZE);
|
||||
memcpy(&TX_Buffer[1] + GRIP_HEADER_SIZE, data->Data, data->Length);
|
||||
|
||||
// Transmit paket
|
||||
ComIf_Send(TX_Buffer, data->Length + GRIP_HEADER_SIZE + 1);
|
||||
|
||||
// Check if we are expecting a response
|
||||
GrIP_Response = RESPONSE_OK;
|
||||
if(MsgType == MSG_DATA)
|
||||
{
|
||||
GrIP_Response = RESPONSE_WAIT;
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
else // Response
|
||||
{
|
||||
// No data available -> Response
|
||||
// No data to transmit, only header
|
||||
TX_Header.Length = 0;
|
||||
|
||||
memcpy(TX_Buffer, &TX_Header, GRIP_HEADER_SIZE);
|
||||
|
||||
// Transmit paket
|
||||
ComIf_Send(TX_Buffer, GRIP_HEADER_SIZE);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
// Clear memory
|
||||
memset(&TX_Header, 0, GRIP_HEADER_SIZE);
|
||||
memset(TX_Buffer, 0, GRIP_BUFFER_SIZE);
|
||||
|
||||
return RET_NOK;
|
||||
}
|
||||
|
||||
|
||||
uint8_t GrIP_Receive(RX_Packet_t *pData)
|
||||
{
|
||||
if(pData)
|
||||
{
|
||||
for(uint8_t i = 0; i < GRIP_RX_NUM; i++)
|
||||
{
|
||||
if(RX_Buff[i].isValid)
|
||||
{
|
||||
memcpy(pData, &RX_Buff[i], sizeof(RX_Packet_t));
|
||||
|
||||
// Clear rx slot
|
||||
memset(&RX_Buff[i], 0, sizeof(RX_Packet_t));
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No data available
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t GrIP_ResponseStatus(void)
|
||||
{
|
||||
return GrIP_Response;
|
||||
}
|
||||
|
||||
|
||||
void GrIP_Update(void)
|
||||
{
|
||||
switch(GrIP_Status)
|
||||
{
|
||||
case GRIP_IDLE:
|
||||
// Check if data is available
|
||||
if(ComIf_DataAvailable())
|
||||
{
|
||||
uint8_t magic = 0;
|
||||
|
||||
// Read Magic byte
|
||||
ComIf_Receive(&magic, 1);
|
||||
|
||||
if(magic == MAGIC)
|
||||
{
|
||||
// Received valid packet
|
||||
GrIP_Status = GRIP_RX_HEADER;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GRIP_RX_HEADER:
|
||||
// Check if header is available
|
||||
if(ComIf_DataAvailable() > (GRIP_HEADER_SIZE-1))
|
||||
{
|
||||
uint8_t head_buff[GRIP_HEADER_SIZE] = {0};
|
||||
|
||||
// Get header
|
||||
ComIf_Receive(head_buff, GRIP_HEADER_SIZE);
|
||||
|
||||
// Fill struct
|
||||
memcpy(&RX_Buff[GrIP_idx].RX_Header, head_buff, GRIP_HEADER_SIZE);
|
||||
|
||||
// Convert length to host order
|
||||
RX_Buff[GrIP_idx].RX_Header.Length = ntohs(RX_Buff[GrIP_idx].RX_Header.Length);
|
||||
|
||||
// Check if header is valid
|
||||
uint8_t ret = CheckHeader(&RX_Buff[GrIP_idx].RX_Header);
|
||||
if(ret != RET_OK)
|
||||
{
|
||||
// Header is invalid
|
||||
GrIP_Status = GRIP_IDLE;
|
||||
//Printf("Wrong header: %d\n", ret);
|
||||
break;
|
||||
}
|
||||
if(RX_Buff[GrIP_idx].RX_Header.Length > GRIP_BUFFER_SIZE)
|
||||
{
|
||||
// Payload too big
|
||||
GrIP_Status = GRIP_IDLE;
|
||||
//Printf("Payload exceeds limit: %d\n", RX_Buff[GrIP_idx].RX_Header.Length);
|
||||
break;
|
||||
}
|
||||
|
||||
// If payload is available
|
||||
if(RX_Buff[GrIP_idx].RX_Header.Length)
|
||||
{
|
||||
// Payload is available
|
||||
GrIP_Status = GRIP_RX_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No payload
|
||||
GrIP_Status = GRIP_IDLE;
|
||||
|
||||
RX_Buff[GrIP_idx].isValid = 1;
|
||||
|
||||
if(GrIP_idx < (GRIP_RX_NUM-1))
|
||||
{
|
||||
GrIP_idx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
GrIP_idx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GRIP_RX_DATA:
|
||||
// Check if entire payload is available
|
||||
if(ComIf_DataAvailable() > (RX_Buff[GrIP_idx].RX_Header.Length-1))
|
||||
{
|
||||
// Get payload
|
||||
//GenIf_Receive(RX_Buffer, RX_Header.Length);
|
||||
ComIf_Receive(RX_Buff[GrIP_idx].Data, RX_Buff[GrIP_idx].RX_Header.Length);
|
||||
if(RX_Buff[GrIP_idx].RX_Header.CRC8 == CRC_CalculateCRC8(RX_Buff[GrIP_idx].Data, RX_Buff[GrIP_idx].RX_Header.Length))
|
||||
{
|
||||
RX_Buff[GrIP_idx].isValid = 1;
|
||||
|
||||
if(GrIP_idx < (GRIP_RX_NUM-1))
|
||||
{
|
||||
GrIP_idx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
GrIP_idx = 0;
|
||||
}
|
||||
}
|
||||
GrIP_Status = GRIP_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Check for new data
|
||||
ComIf_Update();
|
||||
}
|
||||
|
||||
|
||||
static uint8_t CheckHeader(GrIP_PacketHeader_t *paket)
|
||||
{
|
||||
if(paket->Version != GRIP_VERSION)
|
||||
{
|
||||
// Wrong version
|
||||
return RET_WRONG_VERSION;
|
||||
}
|
||||
|
||||
if(paket->MsgType >= MSG_MAX_NUM)
|
||||
{
|
||||
// Wrong message type
|
||||
return RET_WRONG_TYPE;
|
||||
}
|
||||
|
||||
// Everything OK
|
||||
return RET_OK;
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
GrIP.h - GRBL over IP
|
||||
|
||||
Copyright (c) 2018-2019 Patrick F.
|
||||
|
||||
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 3 of the License, or
|
||||
(at your option) 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.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef GRIP_H_INCLUDED
|
||||
#define GRIP_H_INCLUDED
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
// Current protocol version
|
||||
#define GRIP_VERSION 1
|
||||
|
||||
// Transmit/Receive buffer size - Do not exceed (GRIP_BUFFER_SIZE - 10)
|
||||
#define GRIP_BUFFER_SIZE 256
|
||||
#define GRIP_RX_NUM 3
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Available message types.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MSG_SYSTEM_CMD = 0,
|
||||
MSG_REALTIME_CMD = 1,
|
||||
MSG_DATA = 2,
|
||||
MSG_DATA_NO_RESPONSE = 3,
|
||||
MSG_NOTIFICATION = 4,
|
||||
MSG_RESPONSE = 5,
|
||||
MSG_ERROR = 6,
|
||||
MSG_MAX_NUM = 7
|
||||
} MessageType_e;
|
||||
|
||||
|
||||
/**
|
||||
* Return Types.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
RET_OK = 0,
|
||||
RET_NOK = 1,
|
||||
RET_WRONG_VERSION = 2,
|
||||
RET_WRONG_CRC = 3,
|
||||
RET_WRONG_MAGIC = 4,
|
||||
RET_WRONG_PARAM = 5,
|
||||
RET_WRONG_TYPE = 6
|
||||
} ReturnType_e;
|
||||
|
||||
|
||||
/**
|
||||
* Types for response status.
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
RESPONSE_OK = 0,
|
||||
RESPONSE_WAIT = 1,
|
||||
RESPONSE_FAIL = 2
|
||||
} ResponseStatus_e;
|
||||
|
||||
|
||||
/**
|
||||
* GrIP Packet Header
|
||||
*/
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Version;
|
||||
uint8_t MsgType;
|
||||
uint8_t ReturnCode;
|
||||
uint16_t Length;
|
||||
uint8_t CRC8;
|
||||
uint8_t Counter;
|
||||
} GrIP_PacketHeader_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
/**
|
||||
* GrIP Receive Packet
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
GrIP_PacketHeader_t RX_Header;
|
||||
uint8_t isValid;
|
||||
uint8_t Data[GRIP_BUFFER_SIZE];
|
||||
} RX_Packet_t;
|
||||
|
||||
|
||||
/**
|
||||
* Data struct.
|
||||
* Data: Pointer to data.
|
||||
* Length: Length of data in bytes.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *Data;
|
||||
uint16_t Length;
|
||||
} Pdu_t;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the module
|
||||
*/
|
||||
void GrIP_Init(void);
|
||||
|
||||
/**
|
||||
* Transmit a message over GrIP
|
||||
*/
|
||||
uint8_t GrIP_Transmit(uint8_t MsgType, uint8_t ReturnCode, Pdu_t *data);
|
||||
|
||||
/**
|
||||
* Returns the current response state
|
||||
*/
|
||||
uint8_t GrIP_ResponseStatus(void);
|
||||
|
||||
/**
|
||||
* Get data if available
|
||||
*/
|
||||
uint8_t GrIP_Receive(RX_Packet_t *pData);
|
||||
|
||||
/**
|
||||
* Continuously call this function to process RX messages
|
||||
*/
|
||||
void GrIP_Update(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // GRIP_H_INCLUDED
|
|
@ -25,7 +25,7 @@
|
|||
// USART used for Printf(...)
|
||||
#define STDOUT USART2
|
||||
#define STDOUT_NUM USART2_NUM
|
||||
#define STDOUT_BAUD 230400
|
||||
//#define STDOUT_BAUD 115200
|
||||
|
||||
|
||||
//---- Defines ----//
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "USART.h"
|
||||
#include "FIFO_USART.h"
|
||||
#include "Settings.h"
|
||||
#include "GrIP.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
#include "Protocol.h"
|
||||
#include "MotionControl.h"
|
||||
|
||||
#include "GrIP.h"
|
||||
#include "Platform.h"
|
||||
#include "ServerTCP.h"
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
|
||||
|
@ -254,8 +258,24 @@ void Protocol_AutoCycleStart(void)
|
|||
// limit switches, or the main program.
|
||||
void Protocol_ExecuteRealtime(void)
|
||||
{
|
||||
RX_Packet_t packet;
|
||||
|
||||
Protocol_ExecRtSystem();
|
||||
|
||||
#ifdef ETH_IF
|
||||
GrIP_Update();
|
||||
if(GrIP_Receive(&packet))
|
||||
{
|
||||
for(int i = 0; i < packet.RX_Header.Length; i++)
|
||||
{
|
||||
ProcessReceive(packet.Data[i]);
|
||||
}
|
||||
}
|
||||
ServerTCP_Update();
|
||||
#else
|
||||
(void)packet;
|
||||
#endif
|
||||
|
||||
if(sys.suspend) {
|
||||
Protocol_ExecRtSuspend();
|
||||
}
|
||||
|
|
|
@ -409,6 +409,9 @@ void Report_GCodeModes(void)
|
|||
report_util_gcode_modes_G();
|
||||
Printf("%d", 94-gc_state.modal.feed_rate);
|
||||
|
||||
report_util_gcode_modes_G();
|
||||
Printf("%d", 98+gc_state.modal.retract);
|
||||
|
||||
if(gc_state.modal.program_flow) {
|
||||
report_util_gcode_modes_M();
|
||||
|
||||
|
|
27
main.c
27
main.c
|
@ -23,9 +23,15 @@
|
|||
|
||||
#include "System32.h"
|
||||
#include "grbl_advance.h"
|
||||
#include "Ethernet.h"
|
||||
#include "GrIP.h"
|
||||
#include "ServerTCP.h"
|
||||
#include "util2.h"
|
||||
|
||||
#include "Print.h"
|
||||
#include "FIFO_USART.h"
|
||||
#include "ComIf.h"
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
// Declare system global variable structure
|
||||
|
@ -38,6 +44,16 @@ volatile uint8_t sys_rt_exec_alarm; // Global realtime executor bitflag variab
|
|||
volatile uint8_t sys_rt_exec_motion_override; // Global realtime executor bitflag variable for motion-based overrides.
|
||||
volatile uint8_t sys_rt_exec_accessory_override; // Global realtime executor bitflag variable for spindle/coolant overrides.
|
||||
|
||||
#ifdef ETH_IF
|
||||
uint8_t MAC[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||
|
||||
// IP Address of tcp server
|
||||
IPAddress_t IP = {{192, 168, 1, 20}};
|
||||
IPAddress_t GatewayIP = {{192, 168, 1, 1}};
|
||||
IPAddress_t SubnetMask = {{255, 255, 255, 0}};
|
||||
IPAddress_t MyDns = {{8, 8, 8, 8}};
|
||||
#endif
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
@ -50,6 +66,17 @@ int main(void)
|
|||
|
||||
System_ResetPosition();
|
||||
|
||||
#ifdef ETH_IF
|
||||
// Initialize W5500
|
||||
Ethernet_Init(MAC, &IP, &MyDns, &GatewayIP, &SubnetMask);
|
||||
|
||||
// Initialize TCP server
|
||||
ServerTCP_Init(ETH_SOCK, ETH_PORT);
|
||||
#endif
|
||||
|
||||
// Initialize GrIP protocol
|
||||
GrIP_Init();
|
||||
|
||||
// Init SysTick 1ms
|
||||
SysTick_Init();
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue