- on Sa 25 April 2015
Communication between FPGA and DSP28335
This project want to creat a protocol between FPGA and DSP by using only 16 pins.
注意: VHDL的运行方式永远是并行的,所以进入某一个状态之后,它的输出ACK马上生效,而不像DSP中的C代码,进入一个状态后,需要一步一步执行,到最后才发送ACK信号。
引脚分配/Pin Assignment
Logic in DSP - FSM
I mainly creat two functions: void Read_Adc(int addr0)
and Send ()
.
both of them are totally independent with each other and runs alway from State 0 start.
interrupt void xint2_isr(void)
{
GpioDataRegs.GPBSET.bit.GPIO34 = 1;
//////////////// state 0/////////////////////////
GpioDataRegs.GPACLEAR.bit.GPIO3 = 1;
Gpio_Select(0) ; // GPIO- output
// enter the communication program accroding to the FPGA_CLK
// 0B0010
Read_Adc(3);
//0B0011
Read_Adc(0);
Send(5,7,8); // send the data
GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;
// Acknowledge this interrupt to get more from group 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; //clear the irq-flag
}
1.Read_Adc(); -- Stucture
Je nach den verschiedne addr0, kann es aber underschiedliche Address nach FPGA senden.
0000 -> get the ADC channel 0 value.
0001 -> get the ADC channel 1 value.
0010 -> get the ADC channel 2 value.
0011 -> get all the ADC channels(0,1,2) values.
2.void Send(int data0, int data1, int data2); -- Stucture
NOTE: 原本我是设定成从S10直接到S12,但是其实FPGA是在接收到DSP_ACK = 0的时候才跳转到S8状态,如果没有S11直接马上进入S12的话,发送的数据DATA1会覆盖原来S10发送的地址。如此一来,FPGA内部的代码就不能有效读取地址,判断状态机的跳转了。
Because here the pins that i used are not in a bank or a group and they are distributed. So it is hard to send a Data directly to the DATA register and the Data must be set to the each bit pin one by one. According to the TI
When using the GPxDAT register to change the level of an output pin, you should be cautious not to accidentally change the level of another pin. For example, if you mean to change the output latch level of GPIOA0 by writing to the GPADAT register bit 0, using a read-modify-write instruction. The problem can occur if another I/O port A signal changes level between the read and the write stage of the instruction. You can also change the state of that output latch. You can avoid this scenario by using the GPxSET, GPxCLEAR, and GPxTOGGLE registers to load the output latch instead.
so i always using GPxSET and GPxCLEAR and GPxTOGGLE functions.
An example Code for the data0 value to the 13 Datebus pins.
//////////////// state 12 send the 1st data/////////////////////////
if(state_flag == 11)
{
while(1)
{
FPGA_ACK = GpioDataRegs.GPADAT.bit.GPIO5;
if(FPGA_ACK == 0 )
{
// Gpio_Select(1); // set to input
for(j=1; j <= 13 ; j++)
{
if(getBit(data0, j))
{
//dsp[j] = 1;
switch(j)
{
case 1:
GpioDataRegs.GPASET.bit.GPIO31 = 1;
break;
case 2:
GpioDataRegs.GPASET.bit.GPIO29 = 1;
break;
case 3:
GpioDataRegs.GPASET.bit.GPIO23 = 1;
break;
case 4:
GpioDataRegs.GPASET.bit.GPIO21 = 1;
break;
case 5:
GpioDataRegs.GPASET.bit.GPIO19 = 1;
break;
case 6:
GpioDataRegs.GPASET.bit.GPIO17 = 1;
break;
case 7:
GpioDataRegs.GPASET.bit.GPIO27 = 1;
break;
case 8:
GpioDataRegs.GPASET.bit.GPIO25 = 1;
break;
case 9:
GpioDataRegs.GPCSET.bit.GPIO85 = 1;
break;
case 10:
GpioDataRegs.GPBSET.bit.GPIO49 = 1;
break;
case 11:
GpioDataRegs.GPASET.bit.GPIO11 = 1;
break;
case 12:
GpioDataRegs.GPASET.bit.GPIO9 = 1;
break;
case 13:
GpioDataRegs.GPASET.bit.GPIO7 = 1;
break;
default: break;
}
}
else
{
switch(j)
{
case 1:
GpioDataRegs.GPACLEAR.bit.GPIO31 = 1;
break;
case 2:
GpioDataRegs.GPACLEAR.bit.GPIO29 = 1;
break;
case 3:
GpioDataRegs.GPACLEAR.bit.GPIO23 = 1;
break;
case 4:
GpioDataRegs.GPACLEAR.bit.GPIO21 = 1;
break;
case 5:
GpioDataRegs.GPACLEAR.bit.GPIO19 = 1;
break;
case 6:
GpioDataRegs.GPACLEAR.bit.GPIO17 = 1;
break;
case 7:
GpioDataRegs.GPACLEAR.bit.GPIO27 = 1;
break;
case 8:
GpioDataRegs.GPACLEAR.bit.GPIO25 = 1;
break;
case 9:
GpioDataRegs.GPCCLEAR.bit.GPIO85 = 1;
break;
case 10:
GpioDataRegs.GPBCLEAR.bit.GPIO49 = 1;
break;
case 11:
GpioDataRegs.GPACLEAR.bit.GPIO11 = 1;
break;
case 12:
GpioDataRegs.GPACLEAR.bit.GPIO9 = 1;
break;
case 13:
GpioDataRegs.GPACLEAR.bit.GPIO7 = 1;
break;
default: break;
}
}
}
GpioDataRegs.GPASET.bit.GPIO3 = 1;
state_flag = 13;
break;
}
}
}
// get the Nr. m bit of n from low bit to high bit
int getBit(int n, int m)
{
return (n >(m-1)) & 1;
}
Logic in FPGA(VHDL) - FSM
The FSM is written in 3 process with VHDL. using bi-directional Port in the low level
db: inout std_logic_vector(12 downto 0) := (others => 'Z');
Results
Read_Adc(3);
sending address 0011
VHDL
when S4 =>
if(Adc_address = "0011")then
Adc_buffer1 := "0" & x"aaa";
Adc_buffer2 := "1" & x"000";
Adc_buffer3 := "0" & x"555";
FPGA_ACK <= '0';
end if;
led1 <= "111111";
DSP will storage the ADC values from FPGA to three array.
CORRECT!
2.Send(5,7,8)
The Led will blink !
3.
- TIME for execution of these three functions