разобрался я с указателем этим. Резюмирую:
он должен крутиться пока не перевалит за 16 бит. Обнулять его и приводить к размеру сокета нельзя, т.к. сразу размер принятых данных (регистр Sn_RX_RSR0) будет равен 2048.
исходя из данного указателя мы сами должны высчитать физический адрес начала данных. При этом, если указатель будет равен 4097, то, при сокете 2К, адрес должен начинаться с начала, т.е. 0x6001 - это для нулевого сокета.
делается это так:
Код
uint16_t RX_beginDataAddr =(RX_pointer&(S0_RX_MASK+(SNum*0x0800)))+(S0_RX_BASE+(SNum*0x0800)); // вычислим физ. адрес начала данных
ну и собственно код работы с визнетом. Мой драйвер + закомментированы штатные дрова- можете их использовать- просто пример как с ними работать.
Код
void WIZnet_main (void)
{
WIZ_Init();
uint8_t recv_IP[32];
for (uint8_t i = 0; i < sizeof (recv_IP); i++)
{
recv_IP[i] = 0;
}
uint16_t RX_pointer =0;
#define SNum 0
#define S0_RX_BASE 0x6000 //начало памяти Rx
#define S0_RX_MASK 0x07FF //2K-1
// режим сервера
socket (SNum, Sn_MR_TCP, 3001, 0); //for socket: number, protokol, source port, option ???
while ( !listen (SNum) ) { }
while (IINCHIP_READ (Sn_SR(SNum)) != SOCK_ESTABLISHED) { }
while (IINCHIP_READ (Sn_SR(SNum)) == SOCK_ESTABLISHED) {
uint16_t RX_dataSize; // размер принятых данных
while (!(RX_dataSize = IINCHIP_READ16 (Sn_RX_RSR0(SNum))));
RX_pointer = IINCHIP_READ16 (Sn_RX_RD0(SNum)); // считали указатель RX
uint16_t RX_beginDataAddr =(RX_pointer&(S0_RX_MASK+(SNum*0x0800)))+(S0_RX_BASE+(SNum*0x0800)); // вычислим физ. адрес начала данных
//тут обыграем переполнение буфера RX memory
uint16 src_mask = RX_pointer & getIINCHIP_RxMASK(SNum);
if( (src_mask + RX_dataSize) > getIINCHIP_RxMAX(SNum) )
{
uint16_t upper_size = (S0_RX_MASK + 1 - RX_pointer); //размер первых байт, кот влезли в конец буфера
for (uint16_t i=0; i<upper_size; i++) {
recv_IP[i] = IINCHIP_READ (RX_beginDataAddr + i); // пишем их в массив
}
for (uint16_t i=upper_size; i<RX_dataSize; i++) {
recv_IP[i] = IINCHIP_READ ((S0_RX_BASE+(SNum*0x0800)) + (i - upper_size)); // пишем оставшиеся байты с начала буфера
}
}
else
{ // если данные не вылезли за размер буфера
for (uint16_t i=0; i<RX_dataSize; i++) {
recv_IP[i] = IINCHIP_READ (RX_beginDataAddr + i); // положили данные в массив
}
}
RX_pointer += RX_dataSize; // изменим указатель на длину принятых данных
IINCHIP_WRITE16 ((Sn_RX_RD0(SNum)), RX_pointer);
IINCHIP_WRITE (Sn_CR(SNum), Sn_CR_RECV); // команда на изменение регистра
while( IINCHIP_READ(Sn_CR(SNum)));
RX_pointer = IINCHIP_READ16 (Sn_RX_RD0(SNum)); // считали указатель RX
printf("RX_pointer -> %4d recv_IP -> %s\r\n", RX_pointer, recv_IP);
//
// uint16_t RX_dataSize; // размер принятых данных
// while (!(RX_dataSize = IINCHIP_READ16 (Sn_RX_RSR0(SNum))));
//
// recv (SNum, recv_IP, RX_dataSize);
// printf("recv_IP -> %s \r\n \r\n", recv_IP);
}//while
disconnect (SNum);
close (SNum);
printf("connection closed");
}