Если вдруг кому-либо будет не лень читать, вот мой, уже до неприличия упрощенный, код:
Код: Выделить всё
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
// USART
//////////////////////////////////////////////////////////
void USART_Init( unsigned int baud ){
UBRRH = (unsigned char)(baud>>8);
UBRRL = (unsigned char)baud;
UCSRB = (1<<RXEN)|(1<<TXEN)|(1 << RXCIE );
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}
void USART_Transmit(unsigned char data){
while ( !( UCSRA & (1<<UDRE)) );
UDR = data;
}
void USART_PrintStr(char * str){
int i =0;
while(str[i] != 0){
USART_Transmit(str[i]);
i++;
}
USART_Transmit(10);
USART_Transmit(13);
}
// SPI
//////////////////////////////////////////////////////////
#define SPI_PORTX PORTB
#define SPI_DDRX DDRB
#define SPI_MOSI 5
#define SPI_MISO 6
#define SPI_SCK 7
#define SPI_SS 0
void SPI_Init(void){
DDRB |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(0<<SPI_MISO);
PORTB |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(1<<SPI_MISO);
//SPCR = 0b01010000;
//SPSR = 0b00000000;
SPCR = (1<<SPE)|(1<<MSTR);
SPSR |= (1<<SPI2X);
}
// W5100 RW functions
/////////////////////////////////////////////////////////////////
#define WIZNET_WRITE_OPCODE 0xF0
#define WIZNET_READ_OPCODE 0x0F
void W5100_Write(uint16_t addr,uint8_t data){
// Activate the CS pin
SPI_PORTX &= ~(1<<SPI_SS);
// Start Wiznet W5100 Write OpCode transmission
SPDR = WIZNET_WRITE_OPCODE;
// Wait for transmission complete
while(!(SPSR & (1<<SPIF)));
// Start Wiznet W5100 Address High Bytes transmission
SPDR = (addr & 0xFF00) >> 8;
// Wait for transmission complete
while(!(SPSR & (1<<SPIF)));
// Start Wiznet W5100 Address Low Bytes transmission
SPDR = addr & 0x00FF;
// Wait for transmission complete
while(!(SPSR & (1<<SPIF)));
// Start Data transmission
SPDR = data;
// Wait for transmission complete
while(!(SPSR & (1<<SPIF)));
// CS pin is not active
SPI_PORTX |= (1<<SPI_SS);
}
unsigned char W5100_Read(unsigned int addr){
// Activate the CS pin
SPI_PORTX &= ~(1<<SPI_SS);
// Start Wiznet W5100 Read OpCode transmission
SPDR = WIZNET_READ_OPCODE;
// Wait for transmission complete
while(!(SPSR & (1<<SPIF)));
// Start Wiznet W5100 Address High Bytes transmission
SPDR = (addr & 0xFF00) >> 8;
// Wait for transmission complete
while(!(SPSR & (1<<SPIF)));
// Start Wiznet W5100 Address Low Bytes transmission
SPDR = addr & 0x00FF;
// Wait for transmission complete
while(!(SPSR & (1<<SPIF)));
// Send Dummy transmission for reading the data
SPDR = 0x00;
// Wait for transmission complete
while(!(SPSR & (1<<SPIF)));
// CS pin is not active
SPI_PORTX |= (1<<SPI_SS);
return(SPDR);
}
// W5100 Initialization
//////////////////////////////////////////////////////////
#define MR 0x0000 // Mode Register
#define GAR 0x0001 // Gateway Address: 0x0001 to 0x0004
#define SUBR 0x0005 // Subnet mask Address: 0x0005 to 0x0008
#define SAR 0x0009 // Source Hardware Address (MAC): 0x0009 to 0x000E
#define SIPR 0x000F // Source IP Address: 0x000F to 0x0012
#define RMSR 0x001A // RX Memory Size Register
#define TMSR 0x001B // TX Memory Size Register
void W5100_Init(void)
{
// Ethernet Setup
unsigned char mac_addr[] = {0x00,0x16,0x36,0xDE,0x58,0xF6};
unsigned char ip_addr[] = {192,168,2,10};
unsigned char sub_mask[] = {255,255,255,0};
unsigned char gtw_addr[] = {192,168,2,1};
// Setting the Wiznet W5100 Mode Register: 0x0000
W5100_Write(MR,0x80); // MR = 0b10000000;
_delay_ms(10);
// Setting the Wiznet W5100 Gateway Address (GAR): 0x0001 to 0x0004
USART_PrintStr("Setting GW");
W5100_Write(GAR + 0,gtw_addr[0]);
W5100_Write(GAR + 1,gtw_addr[1]);
W5100_Write(GAR + 2,gtw_addr[2]);
W5100_Write(GAR + 3,gtw_addr[3]);
_delay_ms(10);
USART_PrintStr("Checking GW");
if(W5100_Read(GAR+0) != gtw_addr[0] && W5100_Read(GAR+1) != gtw_addr[1] && W5100_Read(GAR+2) != gtw_addr[2] && W5100_Read(GAR+3) != gtw_addr[3]) {
USART_PrintStr("GW - Not set");
}
else USART_PrintStr("GW - Set");
// Setting the Wiznet W5100 Source Address Register (SAR): 0x0009 to 0x000E
W5100_Write(SAR + 0,mac_addr[0]);
W5100_Write(SAR + 1,mac_addr[1]);
W5100_Write(SAR + 2,mac_addr[2]);
W5100_Write(SAR + 3,mac_addr[3]);
W5100_Write(SAR + 4,mac_addr[4]);
W5100_Write(SAR + 5,mac_addr[5]);
_delay_ms(1);
// Setting the Wiznet W5100 Sub Mask Address (SUBR): 0x0005 to 0x0008
W5100_Write(SUBR + 0,sub_mask[0]);
W5100_Write(SUBR + 1,sub_mask[1]);
W5100_Write(SUBR + 2,sub_mask[2]);
W5100_Write(SUBR + 3,sub_mask[3]);
_delay_ms(1);
// Setting the Wiznet W5100 IP Address (SIPR): 0x000F to 0x0012
W5100_Write(SIPR + 0,ip_addr[0]);
W5100_Write(SIPR + 1,ip_addr[1]);
W5100_Write(SIPR + 2,ip_addr[2]);
W5100_Write(SIPR + 3,ip_addr[3]);
_delay_ms(1);
// Setting the Wiznet W5100 RX and TX Memory Size, we use 2KB for Rx/Tx 4 channels
W5100_Write(0x001A,0x55);
W5100_Write(0x001B,0x55);
}
////////////////////////////////////////////////////////////
int main (void)
{
USART_Init(8);
SPI_Init();
unsigned char gtw_addr[] = {192,168,2,1};
W5100_Write(MR,0x80); // MR = 0b10000000;
_delay_ms(100);
W5100_Write(GAR + 0,gtw_addr[0]);
_delay_ms(100);
if(W5100_Read(GAR+0) != gtw_addr[0]) {
USART_PrintStr("GW0 - Not set");
}
else USART_PrintStr("GW0 - Set");
}
Поправьте меня, если я не прав. Вот такая конструкция может ведь быть индикатором успешной записи в w5100:
Код: Выделить всё
W5100_Write(GAR + 0,gtw_addr[0]);
_delay_ms(100);
if(W5100_Read(GAR+0) != gtw_addr[0]) {
USART_PrintStr("GW0 - Not set");
}
else USART_PrintStr("GW0 - Set");
На Вас одна надежда. Чувствую, впадаю в тупку.