/*
@file w5100.c
*/
#include <stdio.h>
#include <string.h>
#include <avr/interrupt.h>
// #include <avr/io.h>
#include "types.h"
#include "delay.h" // for wait function
#include "w5100.h"
#ifdef __DEF_IINCHIP_PPP__
#include "md5.h"
#endif
static uint8 I_STATUS[MAX_SOCK_NUM];
static uint16 SMASK[MAX_SOCK_NUM]; /**< Variable for Tx buffer MASK in each channel */
static uint16 RMASK[MAX_SOCK_NUM]; /**< Variable for Rx buffer MASK in each channel */
static uint16 SSIZE[MAX_SOCK_NUM]; /**< Max Tx buffer size by each channel */
static uint16 RSIZE[MAX_SOCK_NUM]; /**< Max Rx buffer size by each channel */
static uint16 SBUFBASEADDRESS[MAX_SOCK_NUM]; /**< Tx buffer base address by each channel */
static uint16 RBUFBASEADDRESS[MAX_SOCK_NUM]; /**< Rx buffer base address by each channel */
uint8 getISR(uint8 s)
{
return I_STATUS[s];
}
void putISR(uint8 s, uint8 val)
{
I_STATUS[s] = val;
}
uint16 getIINCHIP_RxMAX(uint8 s)
{
return RSIZE[s];
}
uint16 getIINCHIP_TxMAX(uint8 s)
{
return SSIZE[s];
}
uint16 getIINCHIP_RxMASK(uint8 s)
{
return RMASK[s];
}
uint16 getIINCHIP_TxMASK(uint8 s)
{
return SMASK[s];
}
uint16 getIINCHIP_RxBASE(uint8 s)
{
return RBUFBASEADDRESS[s];
}
uint16 getIINCHIP_TxBASE(uint8 s)
{
return SBUFBASEADDRESS[s];
}
/**
@brief This function writes the data into W5100 registers.
*/
uint8 IINCHIP_WRITE(uint16 addr,uint8 data)
{
// DIRECT MODE I/F
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
IINCHIP_ISR_DISABLE();
*((vuint8*)(addr)) = data;
IINCHIP_ISR_ENABLE();
#elif(__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__) /* INDIRECT MODE I/F */
IINCHIP_ISR_DISABLE();
*((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
*((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
*((vuint8*)IDM_DR) = data;
IINCHIP_ISR_ENABLE();
#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_SPI_MODE__)
//SPI MODE I/F
IINCHIP_ISR_DISABLE();
DDRB = 0x07; // MISO=input, etc.=output
// PB3(MISO), PB2(MOSI), PB1(SCK), PB0(/SS)
PORTB = 0x01; // CS=1, waiting for SPI start
SPCR = 0x50; // SPI mode 0, 4MHz
SPSR = 0x01; // SPI2X=0
PORTB = 0x00; // CS=0, SPI start
SPDR = 0xF0;
while((SPSR&0x80)==0x00);
SPDR = (uint8)((addr & 0xFF00) >> 8);
while((SPSR&0x80)==0x00);
SPDR = (uint8)(addr & 0x00FF);
while((SPSR&0x80)==0x00);
SPDR = data;
while((SPSR&0x80)==0x00);
PORTB = 0x01; // SPI end
// CS=1, waiting for SPI start
IINCHIP_ISR_ENABLE();
#else
#error "unknown bus type"
#endif
return 1;
}
/**
@brief This function reads the value from W5100 registers.
*/
uint8 IINCHIP_READ(uint16 addr)
{
uint8 data;
// DIRECT MODE I/F
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
IINCHIP_ISR_DISABLE();
data = *((vuint8*)(addr));
IINCHIP_ISR_ENABLE();
#elif(__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__)
IINCHIP_ISR_DISABLE();
*((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
*((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
data = *((vuint8*)IDM_DR);
IINCHIP_ISR_ENABLE();
#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_SPI_MODE__)
//SPI MODE I/F
IINCHIP_ISR_DISABLE();
DDRB = 0x07; // MISO=input, etc.=output
// PB3(MISO), PB2(MOSI), PB1(SCK), PB0(/SS)
PORTB = 0x01; // CS=1, waiting for SPI start
SPCR = 0x50; // SPI mode 0, 4MHz
SPSR = 0x01; // SPI2X=0
PORTB = 0x00; // CS=0, SPI start
SPDR = 0x0F;
while((SPSR&0x80)==0x00);
SPDR = (uint8)((addr & 0xFF00) >> 8);
while((SPSR&0x80)==0x00);
SPDR = (uint8)(addr & 0x00FF);
while((SPSR&0x80)==0x00);
SPDR = 0x00; // write dummy data
while((SPSR&0x80)==0x00);
data = SPDR; // read data
PORTB = 0x01; // SPI end
// CS=1, waiting for SPI start
IINCHIP_ISR_ENABLE();
#else
#error "unknown bus type"
#endif
return data;
}
/**
@brief This function writes into W5100 memory(Buffer)
*/
uint16 wiz_write_buf(uint16 addr,uint8* buf,uint16 len)
{
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
IINCHIP_ISR_DISABLE();
memcpy((uint8 *)addr, buf, len);
IINCHIP_ISR_ENABLE();
#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__)
uint16 idx = 0;
IINCHIP_ISR_DISABLE();
*((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
*((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
for (idx = 0; idx < len ; idx++) *((vuint8*)IDM_DR) = buf[idx];
IINCHIP_ISR_ENABLE();
#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_SPI_MODE__)
//SPI MODE I/F
IINCHIP_ISR_DISABLE();
uint16 ii=0;
for(ii=0;ii<len;ii++)
{
DDRB = 0x07; // MISO=input, etc.=output
// PB3(MISO), PB2(MOSI), PB1(SCK), PB0(/SS)
PORTB = 0x01; // CS=1, waiting for SPI start
SPCR = 0x50; // SPI mode 0, 4MHz
SPSR = 0x01; // SPI2X=0
PORTB = 0x00; // CS=0, SPI start
SPDR = 0xF0;
while((SPSR&0x80)==0x00);
SPDR = (uint8)(((addr+ii) & 0xFF00) >> 8);
while((SPSR&0x80)==0x00);
SPDR = (uint8)((addr+ii) & 0x00FF);
while((SPSR&0x80)==0x00);
SPDR = buf[ii];
while((SPSR&0x80)==0x00);
PORTB = 0x01; // SPI end
// CS=1, waiting for SPI start
}
IINCHIP_ISR_ENABLE();
#else
#error "unknown bus type"
#endif
return len;
}
/**
@brief This function reads into W5100 memory(Buffer)
*/
uint16 wiz_read_buf(uint16 addr, uint8* buf,uint16 len)
{
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
IINCHIP_ISR_DISABLE();
memcpy(buf, (uint8 *)addr, len);
IINCHIP_ISR_ENABLE();
#elif(__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_INDIRECT_MODE__)
uint16 idx = 0;
IINCHIP_ISR_DISABLE();
*((vuint8*)IDM_AR0) = (uint8)((addr & 0xFF00) >> 8);
*((vuint8*)IDM_AR1) = (uint8)(addr & 0x00FF);
for (idx = 0; idx < len ; idx++) buf[idx] = *((vuint8*)IDM_DR);
IINCHIP_ISR_ENABLE();
#elif (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_SPI_MODE__)
//SPI MODE I/F
IINCHIP_ISR_DISABLE();
uint16 iii=0;
for (iii=0; iii<len; iii++)
{
DDRB = 0x07; // MISO=input, etc.=output
// PB3(MISO), PB2(MOSI), PB1(SCK), PB0(/SS)
PORTB = 0x01; // CS=1, waiting for SPI start
SPCR = 0x50; // SPI mode 0, 4MHz
SPSR = 0x01; // SPI2X=0
PORTB = 0x00; // CS=0, SPI start
SPDR = 0x0F;
while((SPSR&0x80)==0x00);
SPDR = (uint8)(((addr+iii) & 0xFF00) >> 8);
while((SPSR&0x80)==0x00);
SPDR = (uint8)((addr+iii) & 0x00FF);
while((SPSR&0x80)==0x00);
//for (iii=0; iii<len; iii++)
//{
SPDR = 0x00; // write dummy data
while((SPSR&0x80)==0x00);
buf[iii]=SPDR; // read data
//}
PORTB = 0x01; // SPI end