📄 rtl8309.c
字号:
#include "iot13v.h"
#define SMI_DIR DDRB
#define SMI_OUT PORTB
#define SMI_IN PINB
#define MDIO 0b00000001
#define MDC 0b00000010
#define KEY_IN 0b00100000
#define KEY_OUT 0b00001000
#define WDRF_NEW 0b00001000
#define WDTIF_NEW 0b10000000
#define WDTIE_NEW 0b01000000
#define WDCE_NEW 0b00010000
#define WDE_NEW 0b00001000
#define WDP_1SEC 0b00000111
#define WDP_2SEC 0b00001000
#define WDP_4SEC 0b00100000
#define WDP_8SEC 0b00100001
/*******************************************************************/
/* function declare */
/*******************************************************************/
void SMI_1(void);
void SMI_0(void);
void Delay(unsigned int delay);
//PCIE interrupt program
#pragma interrupt_handler Switch:3
/*******************************************************************/
/* function phototype */
/*******************************************************************/
void RTL8309_Write(unsigned char phy_add,unsigned char reg_add,unsigned int data)
{
unsigned int i;
asm("cli"); //interrupt disabled
for(i=0;i<32;i++)//send preamble,32 1
{
SMI_1();
}
{//01 //send start
SMI_0();
SMI_1();
}
{//01 //send op code,write
SMI_0();
SMI_1();
}
for(i=0;i<5;i++)//send phy address
{
if(phy_add&0x10)
SMI_1();//1
else
SMI_0();//0
phy_add<<=1;
}
for(i=0;i<5;i++)//send reg address
{
if(reg_add&0x10)
SMI_1();//1
else
SMI_0();//0
reg_add<<=1;
}
{//10 //send turn around
SMI_1();//1
SMI_0();//0
}
for(i=0;i<16;i++)//send data
{
if(data&0x8000)
SMI_1();//1
else
SMI_0();//0
data<<=1;
}
asm("sei"); //interrupt enabled
}
//SMI send 1
void SMI_1(void)
{
SMI_OUT|=MDIO;
asm("nop");
asm("nop");
SMI_OUT|=MDC;
asm("nop");
asm("nop");
SMI_OUT&=~MDC;
asm("nop");
asm("nop");
}
//SMI send 0
void SMI_0(void)
{
SMI_OUT&=~MDIO;
asm("nop");
asm("nop");
SMI_OUT|=MDC;
asm("nop");
asm("nop");
SMI_OUT&=~MDC;
asm("nop");
asm("nop");
}
//PCIE interrupt program
void Switch()
{
asm("cli"); //interrupt disabled
if((SMI_IN&KEY_IN)==0) //KEY_IN falling edge
{
Delay(10000);
if((SMI_IN&KEY_IN)==0)//delay to get rid of key dithering
{
RTL8309_Write(1,24,0b0000111000100010); //1<-->5
RTL8309_Write(2,24,0b0000111001001000); //3<-->6
}
}
if((SMI_IN&KEY_OUT)==0) //KEY_OUT falling edge
{
Delay(10000);
if((SMI_IN&KEY_OUT)==0)//delay to get rid of key dithering
{
RTL8309_Write(1,24,0b0000111000100100); //1<-->5
RTL8309_Write(2,24,0b0000111001010000); //3<-->6
}
}
asm("sei"); //interrupt enabled
}
//delay
void Delay(unsigned int delay)
{
unsigned int delay_i;
for(delay_i=0;delay_i<delay;delay_i++)
{
asm("nop");
}
}
/*******************************************************************/
/* main function */
/*******************************************************************/
void main( void )
{
unsigned char j;
//watchdog setup
//delay more than 3 second
for(j=0;j<20;j++)
{
Delay(60000);
asm("wdr"); //reset watchdog counter
}
MCUSR&=~WDRF_NEW; //clear watchdog reset flag
WDTCR|=WDCE_NEW+WDE_NEW; //watchdog start timing
WDTCR|=WDE_NEW+WDP_1SEC; //setup delay time: 1 second
//I/O setup
SMI_DIR|=MDC+MDIO; //set MDIO and MDC output
SMI_DIR&=~(KEY_IN+KEY_OUT); //set KEY_IN and KEY_OUT input
SMI_OUT|=KEY_IN+KEY_OUT; //set KEY_IN and KEY_OUT input
SMI_OUT&=~MDC; //MDC output low to get rising edge later
SMI_OUT&=~MDIO; //MDIO output low , not necessary
//PHY1 init
//RTL8309_Write(0,16,0b1110010001111100); //REG16 setup,global control 0
//RTL8309_Write(1,24,0b0000111001000010); //control 2 and VLAN entry,VLAN B cleared
//PHY2 init
RTL8309_Write(2,4, 0b0000000000000001); //REG4 setup,Auto negotiation
RTL8309_Write(2,0, 0b0011001100000000); //control,restart Auto negotiation
//PHY3 init
//RTL8309_Write(3,24,0b0000111000101000);
//PHY4 init
RTL8309_Write(4,4, 0b0000000000000001); //REG4 setup,Auto negotiation
RTL8309_Write(4,0, 0b0011001100000000); //control,restart Auto negotiation
//PHY5 init
// RTL8309_Write(5,24,0b0000111000101000);
//PHY6 init
// RTL8309_Write(6,24,0b0000111001000010); //control 2 and VLAN entry,VLAN B cleared
GIMSK|=0b00100000; //PCINT0 interrupt enabled
PCMSK|=0b00101000; //PCINT3 and PCINT5 interrupt enabled
//interrupt disabled
asm("sei"); //interrupt enabled
//wait for interrupt
while(1)
{
asm("nop");
asm("nop");
asm("nop");
asm("wdr") //reset watchdog counter
asm("nop");
asm("nop");
asm("nop");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -