Interpretation of the program for DSP2812 to control W5500, 3.22
Interpretation of the program for DSP2812 to control W5500, 3.22
Interpretation of CMD files
Set this pin low to indicate microcomputer mode, and the vector table points to the Boot Rom.
ROM: origin = 0x3FF000, length = 0x000FC0 /* boot ROM available if MP/MCn=0 */
The process starts here.
Let’s look at the storage image again.
allocate program space
PRAMH0: origin = 0x3f8000, length = 0x003000boot ROM available if MP/MCn=0 */
But there is a problem, that is, I occupy the reserved space, because the CMD command shows that the program has insufficient space, and problems are likely to occur. If something goes wrong, the first solution is to put the program space in the external RAM Zone2, because the uploaded data does not take up that much space; the second solution is to change the chip to one with more RAM space.
PAGE 1 is to allocate data space. Pay attention to the correspondence between peripherals and some C data spaces. Generally, the template is two CMD files. I only used one file.
If the MEMORY command defines the location of everything. Then the SECTION command is to allocate all related programs and data to fixed locations.
Interpretation of main function
Some operations such as adding header files will not be described in detail. Including the settings of the folder, what files should be placed, etc.
First define some network-related variables
uint8 server_ip[4]={<!-- -->192,168,1,101};
uint16 server_port=5000;
uint16 local_port=6000;
uint16 len=0;
uint8 buffer[2048];
boot ROM available if MP/MCn=0 * /
Network client port , network client ip , local port ,
len represents the remaining space in the socket cache, and the buffer array stores the data read from the W5500.This will be analyzed below
Initialization of the system
Turn off watchdog;
void DisableDog(void)
{<!-- -->
EALLOW;
SysCtrlRegs.WDCR= 0x0068;
EDIS;
}
Initialize the phase-locked loop and define the clock;
EALLOW;
SysCtrlRegs.PLLCR.bit.DIV = val;
EDIS;
Val is a number, 4-bit PLL Select. Clock=external clock*Val/2
Initialize peripheral clock
SysCtrlRegs.HISPCP.all = 0x0000;
SysCtrlRegs.LOSPCP.all = 0x0002;
SysCtrlRegs.PCLKCR.bit.EVAENCLK=1;
SysCtrlRegs.PCLKCR.bit.EVBENCLK=1;
SysCtrlRegs.PCLKCR.bit.SPIENCLK=1;
These peripheral clocks are generally preset high-speed or low-speed clocks. The high-speed and low-speed clocks are obtained by dividing the main frequency. As shown in the above program code, the high speed is not divided, and the low speed is divided twice, which is divided by 4. The crystal oscillator in this project is 10M, the main frequency is 50M, the high speed is 50M, and the low speed is 12,5M. Events A and B are both high speed. spi is low speed. There is a problem here,The interrupt clock cannot be turned on.
Initialization of SPI GPIO port
The hardware is shown in the figure. The four interfaces are F1, F2, F3, and F4.
void InitSpiaGpio(void)
{<!-- -->
EALLOW;
GpioMuxRegs.GPFMUX.bit.SPISIMOA_GPIOF0=1;
GpioMuxRegs.GPFMUX.bit.SPISOMIA_GPIOF1=1;
GpioMuxRegs.GPFMUX.bit.SPICLKA_GPIOF2=1;
GpioMuxRegs.GPFMUX.bit .SPISTEA_GPIOF3=1;
EDIS;
}
The program is as shown in the figure. It seems that 2812 does not need to set the direction or pull-up.Only needs to be configured as SPI interface, this is doubtful. That is his reuse. If configured as normal IO, write 0 in the temporary register and write 1 in the multiplexed peripheral.
Initialization of SPI reset IO port
There is doubt whether its interrupt needs to be used, according to the figure, gpioa9 configures his io and direction, which is an output. The program code is as shown in the figure
void gpio_config(void)
{<!-- -->
EALLOW;
GpioMuxRegs.GPAMUX.bit.CAP2Q2_GPIOA9=0;//GPA9 RSTn, set to i/o
GpioMuxRegs.GPADIR.bit.GPIOA9= 1;//Direction output ; 1: Output; 0: Input
EDIS;
}
Then there are some operations to turn off interrupts
Initialization of the SPI itself
void spi_init()
{<!-- -->
SpiaRegs.SPICCR.bit.SPISWRESET = 0;//Reset SPI
SpiaRegs.SPICCR.all = 0x000F; //0000 0000 0000 1111
//0~3, byte control 16 bits; 4, disable SPI loopback; 5, reserved; 6, rising output, falling input; 7, reset
SpiaRegs.SPICTL.all = 0x0006; // 00000000 0000 0110 Interrupt is invalid, transmit pin is enabled, host mode is disabled Phase delay disabled interrupt
// Enable master mode, normal phase, // enable talk, and SPI int disabled.
SpiaRegs.SPISTS.all = 0x0000; // Overflow interrupt, disable SPI interrupt; Reset system
SpiaRegs.SPIBRR = 0x0009; //SPI baud rate=12.5M/10=1.25MHZ; 0000 1001
SpiaRegs.SPIPRI.bit.FREE = 1; //Set so breakpoints don't disturb xmission
SpiaRegs.SPICCR.bit.SPISWRESET = 1;
}
Here you need to check the temporary register and make a modification.DSP is used as the host and W5500 is used as the slave.
Baud rate setting
SPICCR register: Bits 0~3 of this register determine the number of bits that are moved as a single character in a transfer sequence.Here we set it to 16 bits.
Bit 6 of this register represents the clock polarity. Two bits are used to determine the SPI transmission and reception methods. One is SPICCR.CLKPOLARITY and the other is SPCTL.CLK_PHASE. There are four ways. But W5500 only supports two types, 0 and 3. The question arises, are the modes of the master and slave machines consistent, or do we only need to set the mode of the master machine. I think we should only use the mode of designing the host, so I set it to mode 0.Send on rising edge, receive on falling edge, no delay
SPIPRI This is set to x 1, interrupts are ignored,There may be problems.
Rebase W5500
void Reset_W5500(void)//reset
{<!-- -->
GpioDataRegs.GPADAT.bit.GPIOA9 = 0;
delay_loop();
GpioDataRegs.GPADAT.bit.GPIOA9 = 1;
delay_loop();
}
Set default network related variables
void set_default(void) //Set the default MAC, IP, GW, SUB, DNS
{<!-- -->
uint8 mac[6]={<!-- -->0x00,0x08,0xdc,0x11, 0x11 ,0x11};
uint8 lip[4]={<!-- -->192,168,1,88};
uint8 sub[4]={<!-- -->255,255,255,0};
uint8 gw[4] = {<!-- -->192,168,1,1};
uint8 dns[4]={<!-- -->8,8,8,8};
memcpy(ConfigMsg.lip, lip, 4);
/ /printf("lip: %d.%d.%d.%d
",lip[0],lip[1],lip[2],lip[3]);
memcpy(ConfigMsg.sub, sub, 4 ) ;
//printf("sub: %d.%d.%d.%d
",sub[0],sub[1],sub[2],sub[3]);
memcpy(ConfigMsg.gw, gw , 4);
//printf("gw: %d.%d.%d.%d
",gw[0],gw[1],gw[2],gw[3]);
memcpy(ConfigMsg.mac , mac,6);
memcpy(ConfigMsg.dns,dns,4);
//printf("dns: %d.%d.%d.%d
",dns[0],dns[1],dns[2 ] ,dns[3]);
ConfigMsg.dhcp=0;
ConfigMsg.debug=1;
ConfigMsg.fw_len=0;
ConfigMsg.state=NORMAL_STATE;
ConfigMsg.sw_ver[0]=FW_VER_HIGH;
ConfigMsg.sw_ver[1]=FW_VER_LOW;
}
When debugging the network, you must change some IP addresses or something.
Set up the network,
Write something to W5500, mac, sub, gw lip.
What deserves attention is the initialization of Socket, adjusting its Socket 0 to 16K
program code:
uint8 txsize[MAX_SOCK_NUM] = {<!-- -->16,0,0,0,0,0,0,0} ; // Select the size of each Socket sending cache for 8 Sockets. There is a setting process in void sysinit() of w5500.c
uint8 rxsize[MAX_SOCK_NUM] = {<!-- -->16,0,0,0 , 0,0,0,0}; //Select 8 Sockets and receive cache size for each Socket. There is a setting process in void sysinit() of w5500.c
while1 program
First, a Switch
reads the value of the Sn_SR register to see if it is 0x13, which
represents the TCP working mode. Then connect according to the port and IP.
case SOCK_INIT:
connect(0, server_ip,server_port);
Then read again. If it is 0x17, it
means the connection is successful. Go to the next step.
Reading this bit, Sn_IR_CON, indicates that the connection is established.
Read Sn_RX_RSR, len=getSn_RX_RSR(0); see how much space there is.
Sn_RX_RSR shows the size of data received and stored in the Socket n receive cache.
len is not 0,
if(len>0)
{<!-- -->
//memset(buffer,'0',strlen(buffer));
recv(0,buffer,len);
send(0,buffer,len);
}
In this way, the data in the w5500 is stored in the buffer array, and then the data in the sendbuffer is sent to the W5500. This completes a LOOPback loop.