Исправлена работа с SPI-памятью
Дописана ещё часть по векторному управлению
This commit is contained in:
parent
9fa169da27
commit
2926985867
@ -10,7 +10,7 @@
|
||||
<rts value="libc.a"/>
|
||||
<createSlaveProjects value=""/>
|
||||
<templateProperties value="id=epwm_ex4_deadband.projectspec.epwm_ex4_deadband"/>
|
||||
<origin value="D:/MotorControlModuleSDFM_TMS320F28388D/export/epwm_test"/>
|
||||
<origin value="C:\ti\c2000\C2000Ware_4_03_00_00\device_support\f2838x\examples\cpu1\epwm\CCS\epwm_ex4_deadband.projectspec"/>
|
||||
<filesToOpen value=""/>
|
||||
<connection value="common/targetdb/connections/TIXDS100v2_Connection.xml"/>
|
||||
<isTargetManual value="false"/>
|
||||
|
||||
@ -48,8 +48,6 @@
|
||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.DIAG_WRAP.1358144771" name="Wrap diagnostic messages (--diag_wrap)" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.DIAG_WRAP" useByScannerDiscovery="false" value="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.DIAG_WRAP.off" valueType="enumerated"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.INCLUDE_PATH.131753599" name="Add dir to #include search path (--include_path, -I)" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.INCLUDE_PATH" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value="${COM_TI_C2000WARE_SOFTWARE_PACKAGE_INCLUDE_PATH}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/src/ExternalEEPROM}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/src/Peripherals}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/Freemaster}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/lib}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/src}"/>
|
||||
@ -67,7 +65,6 @@
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.DIAG_SUPPRESS.842502178" name="Suppress diagnostic <id> (--diag_suppress, -pds)" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.DIAG_SUPPRESS" useByScannerDiscovery="false" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value="10063"/>
|
||||
</option>
|
||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.ADVICE__PERFORMANCE.1461480739" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.ADVICE__PERFORMANCE" value="--advice:performance=all" valueType="string"/>
|
||||
<inputType id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compiler.inputType__C_SRCS.37853400" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compiler.inputType__C_SRCS"/>
|
||||
<inputType id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compiler.inputType__CPP_SRCS.1857696012" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compiler.inputType__CPP_SRCS"/>
|
||||
<inputType id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compiler.inputType__ASM_SRCS.1780292617" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compiler.inputType__ASM_SRCS"/>
|
||||
@ -174,6 +171,8 @@
|
||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.ADVICE__PERFORMANCE.1303868905" name="Provide advice on optimization techniques (--advice:performance)" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.ADVICE__PERFORMANCE" value="--advice:performance=none" valueType="string"/>
|
||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.OPT_FOR_SPACE.1012579466" name="Optimize for code size (--opt_for_space, -ms)" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.OPT_FOR_SPACE" value="false" valueType="boolean"/>
|
||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.OPT_FOR_SPEED.2059015133" name="Speed vs. size trade-offs (--opt_for_speed, -mf)" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.OPT_FOR_SPEED" value="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.OPT_FOR_SPEED.0" valueType="enumerated"/>
|
||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.KEEP_ASM.325327440" name="Keep the generated assembly language (.asm) file (--keep_asm, -k)" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.KEEP_ASM" value="true" valueType="boolean"/>
|
||||
<option id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.SOURCE_INTERLIST.995541716" name="Source interlist" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.SOURCE_INTERLIST" value="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.SOURCE_INTERLIST.C_SRC_INTERLIST" valueType="enumerated"/>
|
||||
<inputType id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compiler.inputType__C_SRCS.1756213859" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compiler.inputType__C_SRCS"/>
|
||||
<inputType id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compiler.inputType__CPP_SRCS.1764449958" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compiler.inputType__CPP_SRCS"/>
|
||||
<inputType id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compiler.inputType__ASM_SRCS.1980500029" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compiler.inputType__ASM_SRCS"/>
|
||||
@ -218,6 +217,7 @@
|
||||
<tool id="com.ti.ccstudio.buildDefinitions.C2000_22.6.exe.compilerDebug.722248393" name="C2000 Compiler" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.exe.compilerDebug.1037353257">
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.INCLUDE_PATH.638189817" name="Add dir to #include search path (--include_path, -I)" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.INCLUDE_PATH" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value="D:/MU/UFC/prj/UFC_Application-feature-sdfm/ufc_app/epwm_test/lib"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/src/vector}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/src/Peripherals}"/>
|
||||
<listOptionValue builtIn="false" value="D:/MU/UFC/prj/UFC_Application-feature-sdfm/ufc_app/epwm_test/src/ExternalEEPROM"/>
|
||||
<listOptionValue builtIn="false" value="D:/MU/UFC/prj/UFC_Application-feature-sdfm/ufc_app/epwm_test/Freemaster"/>
|
||||
|
||||
@ -12,6 +12,8 @@ encoding//CPU1_FLASH/src/Peripherals/subdir_rules.mk=UTF-8
|
||||
encoding//CPU1_FLASH/src/Peripherals/subdir_vars.mk=UTF-8
|
||||
encoding//CPU1_FLASH/src/subdir_rules.mk=UTF-8
|
||||
encoding//CPU1_FLASH/src/subdir_vars.mk=UTF-8
|
||||
encoding//CPU1_FLASH/src/vector/subdir_rules.mk=UTF-8
|
||||
encoding//CPU1_FLASH/src/vector/subdir_vars.mk=UTF-8
|
||||
encoding//CPU1_FLASH/subdir_rules.mk=UTF-8
|
||||
encoding//CPU1_FLASH/subdir_vars.mk=UTF-8
|
||||
encoding//CPU1_RAM/Freemaster/subdir_rules.mk=UTF-8
|
||||
@ -21,10 +23,6 @@ encoding//CPU1_RAM/lib/subdir_vars.mk=UTF-8
|
||||
encoding//CPU1_RAM/makefile=UTF-8
|
||||
encoding//CPU1_RAM/objects.mk=UTF-8
|
||||
encoding//CPU1_RAM/sources.mk=UTF-8
|
||||
encoding//CPU1_RAM/src/ExternalEEPROM/subdir_rules.mk=UTF-8
|
||||
encoding//CPU1_RAM/src/ExternalEEPROM/subdir_vars.mk=UTF-8
|
||||
encoding//CPU1_RAM/src/Peripherals/subdir_rules.mk=UTF-8
|
||||
encoding//CPU1_RAM/src/Peripherals/subdir_vars.mk=UTF-8
|
||||
encoding//CPU1_RAM/src/subdir_rules.mk=UTF-8
|
||||
encoding//CPU1_RAM/src/subdir_vars.mk=UTF-8
|
||||
encoding//CPU1_RAM/subdir_rules.mk=UTF-8
|
||||
|
||||
Binary file not shown.
@ -21,9 +21,7 @@
|
||||
|
||||
void main(void)
|
||||
{
|
||||
|
||||
InitPerif();
|
||||
|
||||
for(;;)
|
||||
{
|
||||
asm (" NOP");
|
||||
|
||||
@ -20,42 +20,75 @@
|
||||
|
||||
|
||||
uint16_t sdata2 = RDSR; // sent data
|
||||
uint16_t rdata2 = 0; // received data
|
||||
uint16_t error2 = 0;
|
||||
uint16_t rdata2[16] ; // received data
|
||||
//uint16_t error2 = 0;
|
||||
|
||||
void Bl25cm1a_en(void)
|
||||
{
|
||||
transmitBData(WREN);
|
||||
while(SpibRegs.SPIFFRX.bit.RXFFST != 1)
|
||||
volatile uint16_t empty;
|
||||
transmitData(WREN);
|
||||
while(SpiRegs.SPIFFRX.bit.RXFFST != 1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
rdata2 = SpibRegs.SPIRXBUF;
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
}
|
||||
|
||||
|
||||
void Bl25cm1a_write(void)
|
||||
{
|
||||
transmitBData(sdata2);
|
||||
|
||||
//
|
||||
// Wait until data is received
|
||||
//
|
||||
while(SpibRegs.SPIFFRX.bit.RXFFST != 1)
|
||||
transmitData(sdata2);
|
||||
transmitData(0xFF);
|
||||
while(SpiRegs.SPIFFRX.bit.RXFFST != 2)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
rdata2 = SpibRegs.SPIRXBUF;
|
||||
|
||||
|
||||
rdata2[0] = SpiRegs.SPIRXBUF;
|
||||
rdata2[1] = SpiRegs.SPIRXBUF;
|
||||
}
|
||||
|
||||
void Bl25cm1a_read(void)
|
||||
#define quant 8
|
||||
|
||||
void Bl25cm1a_read_data(uint32_t Addr)
|
||||
{
|
||||
volatile uint16_t empty, i, j;
|
||||
transmitData(READ);
|
||||
transmitData(Addr>>16);
|
||||
transmitData(Addr>>8);
|
||||
transmitData(Addr);
|
||||
for(i = 0; i<quant; i++) transmitData(0xFF);
|
||||
while(SpiRegs.SPIFFRX.bit.RXFFST != (quant+4))
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
for(j = 0; j<quant; j++)
|
||||
{
|
||||
rdata2[j] = SpiRegs.SPIRXBUF;
|
||||
}
|
||||
}
|
||||
|
||||
void Bl25cm1a_write_data(uint32_t Addr)
|
||||
{
|
||||
volatile uint16_t empty, i, j;
|
||||
transmitData(WRITE);
|
||||
transmitData(Addr>>16);
|
||||
transmitData(Addr>>8);
|
||||
transmitData(Addr);
|
||||
for(i = 0; i<quant; i++) transmitData(rdata2[i]);
|
||||
while(SpiRegs.SPIFFRX.bit.RXFFST != (quant+4))
|
||||
{
|
||||
|
||||
}
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
for(j = 0; j<quant; j++)
|
||||
{
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
void Bl25cm1a_en(void);
|
||||
void Bl25cm1a_write(void);
|
||||
void Bl25cm1a_read(void);
|
||||
void Bl25cm1a_write_data(uint32_t Addr);
|
||||
void Bl25cm1a_read_data(uint32_t Addr);
|
||||
|
||||
#endif /* SRC_BL25CM1A_H_ */
|
||||
|
||||
@ -11,11 +11,14 @@
|
||||
|
||||
#define MAX_BUFFER_SIZE 0x10
|
||||
|
||||
uint16_t sendNowI2C = 0, sendNowSPI = 0;
|
||||
|
||||
|
||||
uint16_t sendNowI2C = 0, sendNowSPIGD25 = 0, sendNowSPIBL25 = 0;
|
||||
uint16_t TestADR = 0;
|
||||
uint16_t NByte = 16;
|
||||
uint16_t WriteI2C = 0;
|
||||
uint16_t Adr = 0;
|
||||
uint32_t SpiAdr = 0;
|
||||
|
||||
uint16_t ArrayForTests[MAX_BUFFER_SIZE] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10};
|
||||
uint16_t ArrayMax[256];
|
||||
@ -37,15 +40,56 @@ void ExtEEPROM_run(void)
|
||||
sendNowI2C = 0;
|
||||
}
|
||||
|
||||
if(sendNowSPI == 1)
|
||||
switch(sendNowSPIGD25)
|
||||
{
|
||||
GD25Q16ETIGR_write();
|
||||
sendNowSPI = 0;
|
||||
case 1:
|
||||
GD25Q16ETIGR_en();
|
||||
sendNowSPIGD25 = 0;
|
||||
break;
|
||||
case 2:
|
||||
GD25Q16ETIGR_write();
|
||||
sendNowSPIGD25 = 0;
|
||||
break;
|
||||
case 3:
|
||||
GD25Q16ETIGR_en();
|
||||
GD25Q16ETIGR_write_data(SpiAdr);
|
||||
sendNowSPIGD25 = 0;
|
||||
break;
|
||||
case 4:
|
||||
GD25Q16ETIGR_read_data(SpiAdr);
|
||||
sendNowSPIGD25 = 0;
|
||||
break;
|
||||
case 5:
|
||||
GD25Q16ETIGR_ReadManufacturerDeviceID();
|
||||
sendNowSPIGD25 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
else if(sendNowSPI == 2)
|
||||
|
||||
switch(sendNowSPIBL25)
|
||||
{
|
||||
Bl25cm1a_write();
|
||||
sendNowSPI = 0;
|
||||
case 1:
|
||||
Bl25cm1a_en();
|
||||
sendNowSPIBL25 = 0;
|
||||
break;
|
||||
case 2:
|
||||
Bl25cm1a_write();
|
||||
sendNowSPIBL25 = 0;
|
||||
break;
|
||||
case 3:
|
||||
Bl25cm1a_en();
|
||||
Bl25cm1a_write_data(SpiAdr);
|
||||
sendNowSPIBL25 = 0;
|
||||
break;
|
||||
case 4:
|
||||
Bl25cm1a_read_data(SpiAdr);
|
||||
sendNowSPIBL25 = 0;
|
||||
break;
|
||||
case 5:
|
||||
Bl25cm1a_en();
|
||||
sendNowSPIBL25 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -7,89 +7,109 @@
|
||||
#include "f28x_project.h"
|
||||
#include "spi_init.h"
|
||||
|
||||
//max adr 0x1FFFFF (2097152 bytes = 2048 Kbytes = 2 Mbyte)
|
||||
#define WriteEnable 0x06
|
||||
#define WriteDisable 0x04
|
||||
#define ReadStatusRegister1 0x05 //(S7-S0) (cont.)
|
||||
#define ReadStatusRegister2 0x35 //(S15-S8) (cont.)
|
||||
#define WriteStatusRegister12 0x01 //S7-S0 S15-S8
|
||||
#define VolatileSRwriteEnable 0x50
|
||||
#define ReadData 0x03 //A23-A16 A15-A8 A7-A0 (D7-D0) (cont.)
|
||||
#define FastRead 0x0B //A23-A16 A15-A8 A7-A0 dummy (D7-D0) (cont.)
|
||||
#define ReadManufacturerDeviceID 0x90
|
||||
#define PageProgram 0x02 //A23-A16 A15-A8 A7-A0 D7-D0
|
||||
#define SectorErase 0x20 //A23-A16 A15-A8 A7-A0
|
||||
#define Chip Erase 0xC7 //0x60
|
||||
|
||||
uint16_t sdata1 = ReadStatusRegister1; // sent data
|
||||
uint16_t rdata1[16]; // received data
|
||||
//uint16_t error1 = 0;
|
||||
|
||||
uint16_t sdata1 = 0x6; // sent data
|
||||
uint16_t rdata1[256]; // received data
|
||||
uint16_t error1 = 0;
|
||||
|
||||
void GD25Q16ETIGR_en(void)
|
||||
{
|
||||
transmitBData(sdata1);
|
||||
while(SpibRegs.SPIFFRX.bit.RXFFST != 1)
|
||||
volatile uint16_t empty;
|
||||
transmitData(WriteEnable);
|
||||
while(SpiRegs.SPIFFRX.bit.RXFFST != 1)
|
||||
{
|
||||
|
||||
}
|
||||
rdata1[0] = SpibRegs.SPIRXBUF;
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
}
|
||||
|
||||
|
||||
void GD25Q16ETIGR_write(void)
|
||||
{
|
||||
uint16_t i;
|
||||
for(i = 0; i<=255; i++)
|
||||
{
|
||||
transmitBData(i);
|
||||
transmitData(sdata1);
|
||||
transmitData(0xFF);
|
||||
while(SpiRegs.SPIFFRX.bit.RXFFST != 2)
|
||||
{
|
||||
|
||||
//
|
||||
// Wait until data is received
|
||||
//
|
||||
while(SpibRegs.SPIFFRX.bit.RXFFST != 1)
|
||||
{
|
||||
|
||||
}
|
||||
rdata1[i] = SpibRegs.SPIRXBUF;
|
||||
}
|
||||
/* transmitData(0x90);
|
||||
|
||||
//
|
||||
// Wait until data is received
|
||||
//
|
||||
while(SpiaRegs.SPIFFRX.bit.RXFFST != 1)
|
||||
{
|
||||
|
||||
}
|
||||
rdata1 = SpiaRegs.SPIRXBUF;
|
||||
|
||||
transmitData(0xFF);
|
||||
|
||||
//
|
||||
// Wait until data is received
|
||||
//
|
||||
while(SpiaRegs.SPIFFRX.bit.RXFFST != 1)
|
||||
{
|
||||
|
||||
}
|
||||
rdata1 = SpiaRegs.SPIRXBUF;
|
||||
|
||||
transmitData(0xFF);
|
||||
|
||||
//
|
||||
// Wait until data is received
|
||||
//
|
||||
while(SpiaRegs.SPIFFRX.bit.RXFFST != 1)
|
||||
{
|
||||
|
||||
}
|
||||
rdata1 = SpiaRegs.SPIRXBUF;
|
||||
transmitData(0xFF);
|
||||
|
||||
//
|
||||
// Wait until data is received
|
||||
//
|
||||
while(SpiaRegs.SPIFFRX.bit.RXFFST != 1)
|
||||
{
|
||||
|
||||
}
|
||||
rdata1 = SpiaRegs.SPIRXBUF;
|
||||
transmitData(0xFF);
|
||||
|
||||
//
|
||||
// Wait until data is received
|
||||
//
|
||||
while(SpiaRegs.SPIFFRX.bit.RXFFST != 1)
|
||||
{
|
||||
|
||||
}
|
||||
rdata1 = SpiaRegs.SPIRXBUF;
|
||||
*/
|
||||
}
|
||||
rdata1[0] = SpiRegs.SPIRXBUF;
|
||||
rdata1[1] = SpiRegs.SPIRXBUF;
|
||||
}
|
||||
|
||||
#define quant 8
|
||||
|
||||
void GD25Q16ETIGR_read_data(uint32_t Addr)
|
||||
{
|
||||
volatile uint16_t empty, i, j;
|
||||
transmitData(ReadData);
|
||||
transmitData(Addr>>16);
|
||||
transmitData(Addr>>8);
|
||||
transmitData(Addr);
|
||||
for(i = 0; i<quant; i++) transmitData(0xFF);
|
||||
while(SpiRegs.SPIFFRX.bit.RXFFST != (quant+4))
|
||||
{
|
||||
|
||||
}
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
for(j = 0; j<quant; j++)
|
||||
{
|
||||
rdata1[j] = SpiRegs.SPIRXBUF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GD25Q16ETIGR_write_data(uint32_t Addr)
|
||||
{
|
||||
volatile uint16_t empty, i, j;
|
||||
transmitData(PageProgram);
|
||||
transmitData(Addr>>16);
|
||||
transmitData(Addr>>8);
|
||||
transmitData(Addr);
|
||||
for(i = 0; i<quant; i++) transmitData(rdata1[i]);
|
||||
while(SpiRegs.SPIFFRX.bit.RXFFST != (quant+4))
|
||||
{
|
||||
|
||||
}
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
for(j = 0; j<quant; j++)
|
||||
{
|
||||
empty = SpiRegs.SPIRXBUF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GD25Q16ETIGR_ReadManufacturerDeviceID(void)
|
||||
{
|
||||
volatile uint16_t empty, i, j;
|
||||
transmitData(ReadManufacturerDeviceID);
|
||||
|
||||
for(i = 0; i<5; i++) transmitData(0xFF);
|
||||
while(SpiRegs.SPIFFRX.bit.RXFFST != (6))
|
||||
{
|
||||
|
||||
}
|
||||
for(j = 0; j<6; j++)
|
||||
{
|
||||
rdata1[j] = SpiRegs.SPIRXBUF;
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,5 +10,8 @@
|
||||
|
||||
void GD25Q16ETIGR_en(void);
|
||||
void GD25Q16ETIGR_write(void);
|
||||
void GD25Q16ETIGR_write_data(uint32_t Addr);
|
||||
void GD25Q16ETIGR_read_data(uint32_t Addr);
|
||||
void GD25Q16ETIGR_ReadManufacturerDeviceID(void);
|
||||
|
||||
#endif /* SRC_GD25Q16ETIGR_H_ */
|
||||
|
||||
@ -109,6 +109,27 @@ uint16_t j = 0;
|
||||
// Function to send data over I2C.
|
||||
//
|
||||
void I2CWrite(uint16_t slaveAddr, uint16_t byteCount, bool sendStopCondition, uint16_t * I2C_TXdata)
|
||||
{
|
||||
|
||||
uint16_t index = 0;
|
||||
|
||||
I2caRegs.I2CSAR.all = slaveAddr; // Slave address
|
||||
I2caRegs.I2CMDR.bit.MST = 0x1;
|
||||
I2caRegs.I2CMDR.bit.TRX = 0x1;
|
||||
I2caRegs.I2CCNT = byteCount;
|
||||
|
||||
for(index=0; index < byteCount; index++)
|
||||
{
|
||||
I2caRegs.I2CDXR.all= I2C_TXdata[index];
|
||||
}
|
||||
|
||||
if(sendStopCondition) I2caRegs.I2CMDR.bit.STP = 0x1;
|
||||
I2caRegs.I2CMDR.bit.STT = 0x1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void I2CWrite1(uint16_t slaveAddr, uint16_t byteCount, bool sendStopCondition, uint16_t * I2C_TXdata)
|
||||
{
|
||||
|
||||
//
|
||||
@ -201,6 +222,7 @@ uint16_t I2CRead(uint16_t slaveAddr, uint16_t byteCount, bool sendStopCondition,
|
||||
TimerTimeouts = 0;
|
||||
while((count < (byteCount))&&(TimerTimeouts < TIME_OVER))
|
||||
{
|
||||
if(count == (byteCount-1)) {I2caRegs.I2CMDR.bit.NACKMOD = 0x1; I2caRegs.I2CMDR.bit.STP = 0x1;}
|
||||
if(I2caRegs.I2CSTR.bit.RRDY ==0x1)
|
||||
{
|
||||
RXdata = I2C_RXdata[count-1] = I2caRegs.I2CDRR.all;
|
||||
@ -212,14 +234,14 @@ uint16_t I2CRead(uint16_t slaveAddr, uint16_t byteCount, bool sendStopCondition,
|
||||
//
|
||||
// Send STOP condition
|
||||
//
|
||||
if(sendStopCondition)
|
||||
{
|
||||
I2caRegs.I2CMDR.bit.STP = 0x1;
|
||||
TimerTimeouts = 0;
|
||||
while((I2caRegs.I2CMDR.bit.STP != 0x0)&&(TimerTimeouts < TIME_OVER));
|
||||
if(TimerTimeouts >= TIME_OVER) ErrI2c3++;
|
||||
I2caRegs.I2CSTR.bit.BYTESENT = 0x1;
|
||||
}
|
||||
// if(sendStopCondition)
|
||||
// {
|
||||
// I2caRegs.I2CMDR.bit.STP = 0x1;
|
||||
// TimerTimeouts = 0;
|
||||
// while((I2caRegs.I2CMDR.bit.STP != 0x0)&&(TimerTimeouts < TIME_OVER));
|
||||
// if(TimerTimeouts >= TIME_OVER) ErrI2c3++;
|
||||
// I2caRegs.I2CSTR.bit.BYTESENT = 0x1;
|
||||
// }
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -296,6 +318,8 @@ uint16_t I2CWriteRead(uint16_t slaveAddr, uint16_t byteCount, bool sendStopCondi
|
||||
//
|
||||
// Read the received data into RX buffer
|
||||
//
|
||||
|
||||
|
||||
TimerTimeouts = 0;
|
||||
while((count < byteCount)&&(TimerTimeouts < TIME_OVER))
|
||||
{
|
||||
@ -307,7 +331,6 @@ uint16_t I2CWriteRead(uint16_t slaveAddr, uint16_t byteCount, bool sendStopCondi
|
||||
}
|
||||
}
|
||||
if(TimerTimeouts >= TIME_OVER) ErrI2c2 += (byteCount - count);
|
||||
I2caRegs.I2CMDR.bit.NACKMOD = 0x0;
|
||||
|
||||
//
|
||||
// Send STOP condition
|
||||
@ -398,7 +421,7 @@ void I2CWriteReadOnes(uint16_t slaveAddr)
|
||||
while((I2caRegs.I2CSTR.bit.RRDY != 0x1)&&(TimerTimeouts < TIME_OVER));
|
||||
if(TimerTimeouts >= TIME_OVER) ErrI2c2++;
|
||||
else RXdata = I2caRegs.I2CDRR.all;
|
||||
I2caRegs.I2CMDR.bit.NACKMOD = 0x0;
|
||||
I2caRegs.I2CMDR.bit.NACKMOD = 0x1;
|
||||
|
||||
//
|
||||
// Send STOP condition
|
||||
@ -413,72 +436,3 @@ void I2CWriteReadOnes(uint16_t slaveAddr)
|
||||
|
||||
}
|
||||
|
||||
void I2CWriteOnse(uint16_t slaveAddr)
|
||||
{
|
||||
|
||||
//
|
||||
// Locals
|
||||
//
|
||||
//uint16_t index = 0;
|
||||
|
||||
//
|
||||
// Configure slave address
|
||||
//
|
||||
I2caRegs.I2CSAR.all = slaveAddr; // Slave address
|
||||
|
||||
//
|
||||
// Configure I2C as Master Transmitter
|
||||
//
|
||||
I2caRegs.I2CMDR.bit.MST = 0x1;
|
||||
I2caRegs.I2CMDR.bit.TRX = 0x1;
|
||||
|
||||
//
|
||||
//Set Data Count
|
||||
//
|
||||
I2caRegs.I2CCNT = 2;
|
||||
|
||||
//
|
||||
// send Start condition
|
||||
//
|
||||
I2caRegs.I2CMDR.bit.STT = 0x1;
|
||||
|
||||
//
|
||||
//transmit the bytes
|
||||
//
|
||||
|
||||
I2caRegs.I2CDXR.all= 0x80;
|
||||
//
|
||||
//wait till byte is sent
|
||||
//
|
||||
TimerTimeouts = 0;
|
||||
while((I2caRegs.I2CSTR.bit.BYTESENT != 0x1)&&(TimerTimeouts < TIME_OVER));
|
||||
if(TimerTimeouts >= TIME_OVER) ErrI2c++;
|
||||
else Addr = slaveAddr;
|
||||
//
|
||||
//clear the byte sent
|
||||
//
|
||||
I2caRegs.I2CSTR.bit.BYTESENT = 0x1;
|
||||
|
||||
I2caRegs.I2CDXR.all= RXdata;
|
||||
//
|
||||
//wait till byte is sent
|
||||
//
|
||||
TimerTimeouts = 0;
|
||||
while((I2caRegs.I2CSTR.bit.BYTESENT != 0x1)&&(TimerTimeouts < TIME_OVER));
|
||||
if(TimerTimeouts >= TIME_OVER) ErrI2c++;
|
||||
else Addr = slaveAddr;
|
||||
//
|
||||
//clear the byte sent
|
||||
//
|
||||
I2caRegs.I2CSTR.bit.BYTESENT = 0x1;
|
||||
//
|
||||
// Send STOP condition if specified
|
||||
//
|
||||
|
||||
I2caRegs.I2CMDR.bit.STP = 0x1;
|
||||
TimerTimeouts = 0;
|
||||
while((I2caRegs.I2CMDR.bit.STP != 0x0)&&(TimerTimeouts < TIME_OVER));
|
||||
if(TimerTimeouts >= TIME_OVER) ErrI2c1++;
|
||||
I2caRegs.I2CSTR.bit.BYTESENT = 0x1;
|
||||
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
volatile uint16_t AutoChange = 0;
|
||||
volatile uint16_t PWM_out = 0;
|
||||
//volatile uint16_t PWM_motor = PERIOD_2;
|
||||
uint16_t Fault = 0, Fault_fix = 0, Ready = 0;
|
||||
uint16_t Fault = 0, Fault_fix = 0, Ready = 0, Ready_Fix = 0;
|
||||
uint16_t counter1s=0, Step = 0;
|
||||
TMode Mode = OffMode;
|
||||
|
||||
@ -73,6 +73,7 @@ __interrupt void epwm2_isr(void)
|
||||
// GpioDataRegs.GPADAT.bit.GPIO0 = 1;
|
||||
Step++;
|
||||
if(Mode == StepMode) vector_set_angle(Step);
|
||||
vector_klark_park(0,0,0,0);
|
||||
vector_inversion();
|
||||
FMSTR_enable_set();
|
||||
Step++;
|
||||
@ -129,6 +130,10 @@ __interrupt void epwm4_isr(void)
|
||||
__interrupt void epwm5_isr(void)
|
||||
{
|
||||
Ready = GpioDataRegs.GPADAT.bit.GPIO19;
|
||||
if(Ready == 0)
|
||||
{
|
||||
Ready_Fix = 0;
|
||||
}
|
||||
Fault = !GpioDataRegs.GPADAT.bit.GPIO18;
|
||||
if(Fault || Fault_fix)
|
||||
{
|
||||
@ -138,8 +143,6 @@ __interrupt void epwm5_isr(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
// if(AutoChange) pwm_AutoChange(5);
|
||||
// else
|
||||
EPwm5Regs.CMPA.bit.CMPA = PERIOD_BRAKE - PWM_out;
|
||||
}
|
||||
|
||||
|
||||
@ -43,8 +43,8 @@ uint16_t initDone = 0;
|
||||
__interrupt void Sdfm1_ISR(void);
|
||||
__interrupt void Sdfm2_ISR(void);
|
||||
|
||||
volatile float CurrentFactorBrake = FACTOR_CURRENT_BRAKE;
|
||||
volatile float CurrentFactorMotor = FACTOR_CURRENT_MOTOR;
|
||||
volatile float CurrentFactorBrake = FACTOR_CURRENT_BRAKE_A;
|
||||
volatile float CurrentFactorMotor = FACTOR_CURRENT_MOTOR_A;
|
||||
|
||||
void SdfmGpioInit(void)
|
||||
{
|
||||
|
||||
@ -12,8 +12,11 @@
|
||||
#define R_BRAKE 220.0 //mOM
|
||||
#define R_DRW 4.0 //mOM
|
||||
|
||||
#define FACTOR_CURRENT_BRAKE (SDFM_VOLTAGE_MAX/R_BRAKE) //mOM
|
||||
#define FACTOR_CURRENT_MOTOR (SDFM_VOLTAGE_MAX/R_DRW) //mOM
|
||||
#define FACTOR_CURRENT_BRAKE_A (SDFM_VOLTAGE_MAX/R_BRAKE) //A íŕ 32768ĺä.
|
||||
#define FACTOR_CURRENT_MOTOR_A (SDFM_VOLTAGE_MAX/R_DRW) //A íŕ 32768ĺä.
|
||||
|
||||
#define FACTOR_CURRENT_BRAKE (FACTOR_CURRENT_BRAKE_A/32768.0)
|
||||
#define FACTOR_CURRENT_MOTOR (FACTOR_CURRENT_MOTOR_A/32768.0)
|
||||
|
||||
void SdfmGpioInit(void);
|
||||
void SdfmInitEnable(void);
|
||||
|
||||
@ -51,7 +51,7 @@ void SpiAInit(void)
|
||||
//
|
||||
SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
|
||||
SpiaRegs.SPICTL.bit.TALK = 1;
|
||||
SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
|
||||
SpiaRegs.SPICTL.bit.CLK_PHASE = 1;
|
||||
SpiaRegs.SPICTL.bit.SPIINTENA = 0;
|
||||
|
||||
PieCtrlRegs.PIEIER6.bit.INTx1 = 0;
|
||||
@ -76,7 +76,7 @@ void SpiAInit(void)
|
||||
SpiaRegs.SPICCR.bit.SPISWRESET = 1;
|
||||
}
|
||||
|
||||
void SpiaAGpioInit(void)
|
||||
void SpiAGpioInit(void)
|
||||
{
|
||||
EALLOW;
|
||||
|
||||
@ -194,7 +194,7 @@ void SpiBInit(void)
|
||||
SpibRegs.SPICCR.bit.SPISWRESET = 1;
|
||||
}
|
||||
|
||||
void SpiaBGpioInit(void)
|
||||
void SpiBGpioInit(void)
|
||||
{
|
||||
EALLOW;
|
||||
|
||||
|
||||
@ -5,14 +5,38 @@
|
||||
* Author: seklyuts
|
||||
*/
|
||||
|
||||
//#define ExtEEPROM_SPIB
|
||||
|
||||
#ifndef SRC_SPI_INIT_H_
|
||||
#define SRC_SPI_INIT_H_
|
||||
|
||||
void SpiaAGpioInit(void);
|
||||
void SpiAGpioInit(void);
|
||||
void SpiAInit(void);
|
||||
void transmitAData(uint16_t a);
|
||||
|
||||
void SpiaBGpioInit(void);
|
||||
void SpiBGpioInit(void);
|
||||
void SpiBInit(void);
|
||||
void transmitBData(uint16_t a);
|
||||
|
||||
|
||||
|
||||
#ifdef ExtEEPROM_SPIB
|
||||
|
||||
#define SpiGpioInit SpiBGpioInit
|
||||
#define SpiInit SpiBInit
|
||||
#define transmitData transmitBData
|
||||
#define SpiRegs SpibRegs
|
||||
|
||||
#else
|
||||
|
||||
#define SpiGpioInit SpiAGpioInit
|
||||
#define SpiInit SpiAInit
|
||||
#define transmitData transmitAData
|
||||
#define SpiRegs SpiaRegs
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* SRC_SPI_INIT_H_ */
|
||||
|
||||
@ -62,11 +62,31 @@ void FRMUartInit(void)
|
||||
|
||||
//
|
||||
// SCIA at 9600 baud
|
||||
// @LSPCLK = 50 MHz (200 MHz SYSCLK) HBAUD = 0x02 and LBAUD = 0x8B.
|
||||
// @LSPCLK = 50 MHz (200 MHz SYSCLK) HBAUD = 0x02 and LBAUD = 0x8B //8A
|
||||
// @LSPCLK = 30 MHz (120 MHz SYSCLK) HBAUD = 0x01 and LBAUD = 0x86.
|
||||
//
|
||||
SciaRegs.SCIHBAUD.all = 0x0002;
|
||||
SciaRegs.SCILBAUD.all = 0x008B;
|
||||
//
|
||||
// SCIA at 19200 baud
|
||||
// @LSPCLK = 50 MHz (200 MHz SYSCLK) HBAUD = 0x01 and LBAUD = 0x45.
|
||||
//
|
||||
//
|
||||
// SCIA at 38400 baud
|
||||
// @LSPCLK = 50 MHz (200 MHz SYSCLK) HBAUD = 0x00 and LBAUD = 0xA2.
|
||||
//
|
||||
//
|
||||
// SCIA at 56000 baud
|
||||
// @LSPCLK = 50 MHz (200 MHz SYSCLK) HBAUD = 0x00 and LBAUD = 0x6F.
|
||||
//
|
||||
//
|
||||
// SCIA at 57600 baud
|
||||
// @LSPCLK = 50 MHz (200 MHz SYSCLK) HBAUD = 0x00 and LBAUD = 0x6C (6B).
|
||||
//
|
||||
//
|
||||
// SCIA at 115200 baud
|
||||
// @LSPCLK = 50 MHz (200 MHz SYSCLK) HBAUD = 0x00 and LBAUD = 0x35.
|
||||
//
|
||||
SciaRegs.SCIHBAUD.all = 0x0000;
|
||||
SciaRegs.SCILBAUD.all = 0x006F;
|
||||
|
||||
SciaRegs.SCICTL1.all = 0x0023; // Relinquish SCI from Reset
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
* Author: seklyuts
|
||||
*/
|
||||
|
||||
#include <pwm_init.h>
|
||||
#include "pwm_init.h"
|
||||
#include "f28x_project.h"
|
||||
#include "pwm_interrupts.h"
|
||||
#include "sdfm.h"
|
||||
@ -17,6 +17,7 @@
|
||||
#include "BL25CM1A.h"
|
||||
#include "GD25Q16ETIGR.h"
|
||||
#include "ZD24C02A.h"
|
||||
#include "vector.h"
|
||||
|
||||
|
||||
void InitPerif(void)
|
||||
@ -29,7 +30,7 @@ void InitPerif(void)
|
||||
SdfmGpioInit();
|
||||
SdfmInitEnable();
|
||||
|
||||
SpiaBGpioInit();
|
||||
SpiGpioInit();
|
||||
I2CMasterGpioInit();
|
||||
|
||||
|
||||
@ -68,7 +69,7 @@ void InitPerif(void)
|
||||
PWMAllInit();
|
||||
SdfmInitInterruptEn();
|
||||
SdfmInit();
|
||||
SpiBInit();
|
||||
SpiInit();
|
||||
I2CMasterInit(I2C_OWN_ADDRESS,I2C_SLAVE_ADDRESS);
|
||||
//
|
||||
// Enable global Interrupts and higher priority real-time debug events:
|
||||
@ -78,6 +79,7 @@ void InitPerif(void)
|
||||
|
||||
FRMUartInit();
|
||||
GD25Q16ETIGR_en();
|
||||
vectorInitCurrLoop();
|
||||
// Bl25cm1a_en();
|
||||
|
||||
}
|
||||
|
||||
@ -8,8 +8,11 @@
|
||||
|
||||
#include "f28x_project.h"
|
||||
#include "pwm_interrupts.h"
|
||||
#include "pi.h"
|
||||
#include "vector.h"
|
||||
#include "iqmath.h"
|
||||
#include "sdfm.h"
|
||||
|
||||
|
||||
const int16_t mcgenSineTable256[257] = \
|
||||
{ 0,-201,-402,-603,-804,-1005,-1206,-1407,-1607,-1808,
|
||||
@ -39,45 +42,54 @@ const int16_t mcgenSineTable256[257] = \
|
||||
-32610,-32629,-32647,-32663,-32679,-32693,-32706,-32718,-32728,-32737,
|
||||
-32745,-32752,-32758,-32762,-32765,-32767,-32767 };
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float q; //íàïðÿæåíèå Uq, Â
|
||||
float d; //íàïðÿæåíèå Ud, Â
|
||||
}Tvector2dq;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float Alfa; //íàïðÿæåíèå Uq, Â
|
||||
float Beta; //íàïðÿæåíèå Ud, Â
|
||||
}Tvector2ph;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float a; //íàïðÿæåíèå Uq, Â
|
||||
float b; //íàïðÿæåíèå Ud, Â
|
||||
float c; //íàïðÿæåíèå Ud, Â
|
||||
}Tvector3abc;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int16_t Angle;
|
||||
float sin; //íàïðÿæåíèå Uq, Â
|
||||
float cos; //íàïðÿæåíèå Ud, Â
|
||||
}TvectorSinCos;
|
||||
|
||||
Tvector2dq vectorUdq, vectorIdq;
|
||||
Tvector2ph vectorU2ph, vectorI2ph;
|
||||
Tvector3abc vectorUabc, vectorIabc;
|
||||
TvectorSinCos vectorSinCos;
|
||||
uint16_t VecSector;
|
||||
float FactorCurrent = FACTOR_CURRENT_MOTOR;
|
||||
TvectorCurrentLoop CurrLoop;
|
||||
|
||||
void vectorInitCurrLoop(void)
|
||||
{
|
||||
CurrLoop.CurrentLimit = CURRENT_MAX;
|
||||
|
||||
CurrLoop.piId.Ref = 0; // Input: reference set-point
|
||||
CurrLoop.piId.Fbk = 0; // Input: feedback
|
||||
CurrLoop.piId.uCorr = 0; // Input: Êîððåêöèÿ âûõîäà, äëÿ óñòðàíåíèÿ ïåðåêðåòíûõ ñâÿçåé
|
||||
CurrLoop.piId.Out = 0; // Output: controller output
|
||||
CurrLoop.piId.Kp = PI_REG_I_PROPOR; // Parameter: proportional loop gain
|
||||
CurrLoop.piId.Ki = PI_REG_I_INTEGR; // Parameter: integral gain
|
||||
CurrLoop.piId.Umax = VOLT_MAX_PROC; // Parameter: upper saturation limit
|
||||
CurrLoop.piId.Umin = -VOLT_MAX_PROC; // Parameter: lower saturation limit
|
||||
CurrLoop.piId.up = 0; // Data: proportional term
|
||||
CurrLoop.piId.ui = 0; // Data: integral term
|
||||
CurrLoop.piId.v1 = 0; // Data: pre-saturated controller output
|
||||
CurrLoop.piId.i1 = 0; // Data: integrator storage: ui(k-1)
|
||||
|
||||
|
||||
CurrLoop.piIq.Ref = 0; // Input: reference set-point
|
||||
CurrLoop.piIq.Fbk = 0; // Input: feedback
|
||||
CurrLoop.piIq.uCorr = 0; // Input: Êîððåêöèÿ âûõîäà, äëÿ óñòðàíåíèÿ ïåðåêðåòíûõ ñâÿçåé
|
||||
CurrLoop.piIq.Out = 0; // Output: controller output
|
||||
CurrLoop.piIq.Kp = PI_REG_I_PROPOR; // Parameter: proportional loop gain
|
||||
CurrLoop.piIq.Ki = PI_REG_I_INTEGR; // Parameter: integral gain
|
||||
CurrLoop.piIq.Umax = VOLT_MAX_PROC; // Parameter: upper saturation limit
|
||||
CurrLoop.piIq.Umin = -VOLT_MAX_PROC; // Parameter: lower saturation limit
|
||||
CurrLoop.piIq.up = 0; // Data: proportional term
|
||||
CurrLoop.piIq.ui = 0; // Data: integral term
|
||||
CurrLoop.piIq.v1 = 0; // Data: pre-saturated controller output
|
||||
CurrLoop.piIq.i1 = 0; // Data: integrator storage: ui(k-1)
|
||||
}
|
||||
|
||||
void vector_set_angle(int16_t val)
|
||||
{
|
||||
vectorSinCos.Angle = val;
|
||||
}
|
||||
|
||||
int16_t mcsinPIxLUT(int16_t Value, int16_t *psinTable)
|
||||
int16_t vector_mcsinPIxLUT(int16_t Value, int16_t *psinTable)
|
||||
{
|
||||
// set saturation on
|
||||
if (Value>=0)
|
||||
@ -99,8 +111,8 @@ void vector_inversion(void)
|
||||
{
|
||||
float temp1, temp2, temp3;
|
||||
|
||||
vectorSinCos.sin = ((float)mcsinPIxLUT(vectorSinCos.Angle, (int16_t *)&mcgenSineTable256))/32768.0;
|
||||
vectorSinCos.cos = ((float)mcsinPIxLUT((vectorSinCos.Angle + ANGLE_PI_DIVIDE_2_F16),(int16_t *)&mcgenSineTable256))/32768.0;
|
||||
// vectorSinCos.sin = ((float)mcsinPIxLUT(vectorSinCos.Angle, (int16_t *)&mcgenSineTable256))/32768.0;
|
||||
// vectorSinCos.cos = ((float)mcsinPIxLUT((vectorSinCos.Angle + ANGLE_PI_DIVIDE_2_F16),(int16_t *)&mcgenSineTable256))/32768.0;
|
||||
|
||||
vectorU2ph.Alfa = _IQmpy(vectorUdq.d,vectorSinCos.cos) - _IQmpy(vectorUdq.q,vectorSinCos.sin);
|
||||
vectorU2ph.Beta = _IQmpy(vectorUdq.q,vectorSinCos.cos) + _IQmpy(vectorUdq.d,vectorSinCos.sin);
|
||||
@ -136,16 +148,12 @@ void vector_inversion(void)
|
||||
pwm_set_volt_3F(vectorUabc.a,vectorUabc.b,vectorUabc.c);
|
||||
}
|
||||
|
||||
float Test1, Test2;
|
||||
|
||||
|
||||
|
||||
void vector_klark_park(uint16_t SectorOn)
|
||||
void vector_klark_park(uint16_t SectorOn, int16_t CurrentA, int16_t CurrentB, int16_t CurrentC)
|
||||
{
|
||||
|
||||
//Ôèëüòðóåì íàïðÿæåíèå â çâåíå ïîñòîÿííîãî òîêà(ïåðåâîäèì åãî èç îòñ÷åòîâ ÀÖÏ â Âîëüòû)
|
||||
// FILTER_FL(PmsmVect.UdcFilter, ((float)Inputs->UdcAdc * PmsmVect.FactorUdc));
|
||||
|
||||
|
||||
/* if (Inputs->UpdateUdc)
|
||||
{
|
||||
//Çàïîìèíàåì Udc äëÿ êîíòóðà òîêà(îãðàíè÷åíèå Umax è Umin â ÏÈ-ðåãóëÿòîðå)
|
||||
@ -160,57 +168,117 @@ void vector_klark_park(uint16_t SectorOn)
|
||||
}*/
|
||||
|
||||
|
||||
//Âûïîëíåíèå ïðåîáðàçîâàíèå Êëàðêà
|
||||
/* PmsmVect.AdcZeroCurr[e_phaseA] = PmsmVect.AdcZeroLvl[e_phaseA] - Inputs->Adc[e_phaseA];
|
||||
PmsmVect.AdcZeroCurr[e_phaseB] = PmsmVect.AdcZeroLvl[e_phaseB] - Inputs->Adc[e_phaseB];
|
||||
PmsmVect.AdcZeroCurr[e_phaseC] = PmsmVect.AdcZeroLvl[e_phaseC] - Inputs->Adc[e_phaseC];
|
||||
|
||||
if (SectorOn )
|
||||
{
|
||||
switch (PmsmVect.Svgen.VecSector) {
|
||||
switch (VecSector) {
|
||||
case 2:
|
||||
case 3:
|
||||
PmsmVect.Clarke.As = PmsmVect.AdcZeroCurr[e_phaseA] * PmsmVect.FactorCurrent;
|
||||
PmsmVect.Clarke.Cs = PmsmVect.AdcZeroCurr[e_phaseC] * PmsmVect.FactorCurrent;
|
||||
PmsmVect.Clarke.Bs = - PmsmVect.Clarke.As - PmsmVect.Clarke.Cs;
|
||||
vectorIabc.a = (float)CurrentA * FactorCurrent;
|
||||
vectorIabc.c = (float)CurrentC * FactorCurrent;
|
||||
vectorIabc.b = - vectorIabc.a - vectorIabc.c;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
PmsmVect.Clarke.As = PmsmVect.AdcZeroCurr[e_phaseA] * PmsmVect.FactorCurrent;
|
||||
PmsmVect.Clarke.Bs = PmsmVect.AdcZeroCurr[e_phaseB] * PmsmVect.FactorCurrent;
|
||||
PmsmVect.Clarke.Cs = - PmsmVect.Clarke.As - PmsmVect.Clarke.Bs;
|
||||
vectorIabc.a = (float)CurrentA * FactorCurrent;
|
||||
vectorIabc.b = (float)CurrentB * FactorCurrent;
|
||||
vectorIabc.c = - vectorIabc.a - vectorIabc.b;
|
||||
break;
|
||||
case 1:
|
||||
case 6:
|
||||
default:
|
||||
PmsmVect.Clarke.Bs = PmsmVect.AdcZeroCurr[e_phaseB] * PmsmVect.FactorCurrent;
|
||||
PmsmVect.Clarke.Cs = PmsmVect.AdcZeroCurr[e_phaseC] * PmsmVect.FactorCurrent;
|
||||
PmsmVect.Clarke.As = - PmsmVect.Clarke.Bs - PmsmVect.Clarke.Cs;
|
||||
vectorIabc.b = (float)CurrentB * FactorCurrent;
|
||||
vectorIabc.c = (float)CurrentC * FactorCurrent;
|
||||
vectorIabc.a = - vectorIabc.b - vectorIabc.c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PmsmVect.Clarke.As = PmsmVect.AdcZeroCurr[e_phaseA] * PmsmVect.FactorCurrent; //ADC -> A
|
||||
PmsmVect.Clarke.Bs = PmsmVect.AdcZeroCurr[e_phaseB] * PmsmVect.FactorCurrent;
|
||||
PmsmVect.Clarke.Cs = PmsmVect.AdcZeroCurr[e_phaseC] * PmsmVect.FactorCurrent;
|
||||
vectorIabc.a = (float)CurrentA * FactorCurrent;
|
||||
vectorIabc.b = (float)CurrentB * FactorCurrent;
|
||||
vectorIabc.c = (float)CurrentC * FactorCurrent;
|
||||
}
|
||||
CLARKE_MACRO1(PmsmVect.Clarke);
|
||||
|
||||
// ïðåîáðàçîâàíèå Êëàðê
|
||||
|
||||
//Ïåðåâîä èç îòñ÷åòîâ äàò÷èêà ðîòîðà â ýëåêòðè÷åñêèå ðàäèàíû
|
||||
PmsmVect.Park.Angle = Inputs->Angle * PmsmVect.FactorAngle; //îòñ÷. ìåõ. -> ðàä. ýë.
|
||||
vectorI2ph.Alfa = vectorIabc.a;
|
||||
vectorI2ph.Beta = _IQmpy((vectorIabc.a +_IQmpy2(vectorIabc.b)),_IQ(ONEbySQRT3)); //vectorI2ph.Beta = _IQmpy((vectorIabc.b - vectorIabc.c),_IQ(ONEbySQRT3));
|
||||
|
||||
vectorSinCos.sin = ((float)vector_mcsinPIxLUT(vectorSinCos.Angle, (int16_t *)&mcgenSineTable256))/32768.0;
|
||||
vectorSinCos.cos = ((float)vector_mcsinPIxLUT((vectorSinCos.Angle + ANGLE_PI_DIVIDE_2_F16),(int16_t *)&mcgenSineTable256))/32768.0;
|
||||
|
||||
// ïðåîáðàçîâàíèå Ïàðêà
|
||||
PmsmVect.Park.Alpha = PmsmVect.Clarke.Alpha;
|
||||
PmsmVect.Park.Beta = PmsmVect.Clarke.Beta;
|
||||
PmsmVect.iPark.Sine = PmsmVect.Park.Sine = sin(PmsmVect.Park.Angle);
|
||||
PmsmVect.iPark.Cosine = PmsmVect.Park.Cosine = cos(PmsmVect.Park.Angle);
|
||||
PARK_MACRO(PmsmVect.Park);
|
||||
vectorIdq.d = _IQmpy(vectorI2ph.Alfa,vectorSinCos.cos) + _IQmpy(vectorI2ph.Beta,vectorSinCos.sin);
|
||||
vectorIdq.q = _IQmpy(vectorI2ph.Beta,vectorSinCos.cos) - _IQmpy(vectorI2ph.Alfa,vectorSinCos.sin);
|
||||
|
||||
Outputs->IqFbk = PmsmVect.Park.Qs;
|
||||
Outputs->IdFbk = PmsmVect.Park.Ds;*/
|
||||
|
||||
|
||||
// CurrLoop.piIq.Ref = Inputs->IqRef;//Çàäàííîå
|
||||
|
||||
if (FABS(CurrLoop.piIq.Ref) > CurrLoop.CurrentLimit)
|
||||
{
|
||||
(CurrLoop.piIq.Ref >= 0.0f) ? ( CurrLoop.piIq.Ref = CurrLoop.CurrentLimit ) :
|
||||
( CurrLoop.piIq.Ref = -CurrLoop.CurrentLimit);
|
||||
}
|
||||
|
||||
CurrLoop.piIq.Fbk = vectorIdq.q;
|
||||
|
||||
CurrLoop.piId.Ref = 0;
|
||||
CurrLoop.piId.Fbk = vectorIdq.d;
|
||||
|
||||
// CurrLoop.piId.Umax = CurrLoop.piIq.Umax = Inputs->Udc;
|
||||
// CurrLoop.piId.Umin = CurrLoop.piIq.Umin = -CurrLoop.piIq.Umax;
|
||||
#ifdef UCORR_ENABLE
|
||||
//Ïåðåêðåñòíûå ñâÿçè
|
||||
float Velectr = VFbk * CurrLoop.VelElectrFactor;
|
||||
CurrLoop.piId.uCorr = Velectr * CurrLoop.PhaseInduct * CurrLoop.piIq.Fbk;
|
||||
CurrLoop.piIq.uCorr = -Velectr * (CurrLoop.FluxLinkage + CurrLoop.PhaseInduct * CurrLoop.piId.Fbk);
|
||||
#else
|
||||
CurrLoop.piId.uCorr = CurrLoop.piIq.uCorr = 0.0f;
|
||||
#endif
|
||||
|
||||
PI_MACRO(CurrLoop.piId);
|
||||
PI_MACRO(CurrLoop.piIq);
|
||||
|
||||
/*Ïðîïîðöèîíàëüíîå îãðàíè÷åíèå íàïðÿæåíèé Uq è Ud*/
|
||||
// Test1 = my_sqrtf(Test2);
|
||||
|
||||
float Ulim = my_sqrtf(CurrLoop.piId.Out * CurrLoop.piId.Out + CurrLoop.piIq.Out * CurrLoop.piIq.Out);
|
||||
if (Ulim > VOLT_MAX_PROC)
|
||||
{
|
||||
if(Ulim > ZERO_LVL)
|
||||
{
|
||||
float K = VOLT_MAX_PROC / Ulim;
|
||||
CurrLoop.piId.Out *= K;
|
||||
CurrLoop.piIq.Out *= K;
|
||||
}
|
||||
}
|
||||
|
||||
// vectorUdq.q = CurrLoop.piIq.Out;
|
||||
// vectorUdq.d = CurrLoop.piId.Out;
|
||||
}
|
||||
|
||||
float my_sqrtf(float x)
|
||||
{
|
||||
if (x == 0) return x;
|
||||
|
||||
/*
|
||||
* We'll compute 1/sqrt(x) using the Newton-Raphson method from an
|
||||
* initial approximation using EISQRTF32; this instruction gives
|
||||
* 1/sqrtf(x) "accurate to approximately 8 bits" (SPRUEO2A). The
|
||||
* number of iterations used here may not be optimal for this
|
||||
* instruction.
|
||||
*
|
||||
* n.b. __eisqrtf32 cannot generate -0, NaN, or denormal values
|
||||
*
|
||||
* n.b. this loop is divergent for very small x
|
||||
*/
|
||||
|
||||
float x0 = __eisqrtf32(x);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
x0 *= (1.5f - x * 0.5f * x0 * x0);
|
||||
|
||||
/* now sqrt(x) = x * 1/sqrt(x) */
|
||||
return x * x0;
|
||||
}
|
||||
|
||||
@ -5,9 +5,14 @@
|
||||
* Author: seklyuts
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef SRC_VECTOR_H_
|
||||
#define SRC_VECTOR_H_
|
||||
|
||||
#include "pi.h"
|
||||
#include "pwm_init.h"
|
||||
|
||||
#define sng(x) ((x)?((x>0)?1:(-1)):(0))
|
||||
#define max(a,b) ((a>b)?a:b)
|
||||
#define min(a,b) ((a<b)?a:b)
|
||||
@ -28,11 +33,52 @@
|
||||
#define SIN_INDEX_SHIFT 6
|
||||
#define SIN_LENGTH_TABLE 256
|
||||
|
||||
#define VOLT_MAX_PROC PWM_MAX
|
||||
#define PI_REG_I_PROPOR 0
|
||||
#define PI_REG_I_INTEGR 0
|
||||
#define CURRENT_MAX 40.0 //A
|
||||
#define ZERO_LVL 0.000001f
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float q;
|
||||
float d;
|
||||
}Tvector2dq;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float Alfa;
|
||||
float Beta;
|
||||
}Tvector2ph;
|
||||
|
||||
int16_t mcsinPIxLUT(int16_t Value, int16_t *psinTable);
|
||||
typedef struct
|
||||
{
|
||||
float a;
|
||||
float b;
|
||||
float c;
|
||||
}Tvector3abc;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int16_t Angle;
|
||||
float sin;
|
||||
float cos;
|
||||
}TvectorSinCos;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float CurrentLimit; //A
|
||||
PI_CONTROLLER piIq;
|
||||
PI_CONTROLLER piId;
|
||||
}TvectorCurrentLoop;
|
||||
|
||||
|
||||
int16_t vector_mcsinPIxLUT(int16_t Value, int16_t *psinTable);
|
||||
void vector_inversion(void);
|
||||
void vector_klark_park(uint16_t SectorOn, int16_t CurrentA, int16_t CurrentB, int16_t CurrentC);
|
||||
void vector_set_angle(int16_t val);
|
||||
void vectorInitCurrLoop(void);
|
||||
float my_sqrtf(float x);
|
||||
|
||||
#endif /* SRC_VECTOR_H_ */
|
||||
|
||||
64
Projects/epwm_test/src/vector/iqmath.h
Normal file
64
Projects/epwm_test/src/vector/iqmath.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
*========================================================================================
|
||||
* (C) Copyright 2019 ŔÎ "Äčŕęîíň"
|
||||
* ă. Ńŕíęň-Ďĺňĺđáóđă, Đîńńč˙
|
||||
*
|
||||
* Ôŕéë: iqmath.h
|
||||
* Îďčńŕíčĺ: Đĺŕëčçŕöč˙ âű÷čńëĺíčé iq
|
||||
*
|
||||
*========================================================================================
|
||||
*/
|
||||
#ifndef IQMATH_H_
|
||||
#define IQMATH_H_
|
||||
/*
|
||||
*----------------------------------------------------------------------------------------
|
||||
*Âęëţ÷ŕĺěűĺ ôŕéëű
|
||||
*----------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------------------
|
||||
*Îáú˙âëĺíč˙ ěŕęđîńîâ
|
||||
*----------------------------------------------------------------------------------------
|
||||
*/
|
||||
#define _IQsat(A, Pos, Neg) (__fmax(((__fmin((A),(Pos)))),(Neg)))
|
||||
#define _IQ(A) (A)
|
||||
#define _IQmpy(A, B) ((A) * (B))
|
||||
#define _IQdiv2(A) ((A) * 0.5f)
|
||||
#define _IQmpy2(A) ((A) * 2.0f)
|
||||
|
||||
#define IQtoQ5(A) (long) ((A) * 32.0f)
|
||||
#define IQtoQ6(A) (long) ((A) * 64.0f)
|
||||
#define IQtoQ8(A) (long) ((A) * 256.0f)
|
||||
#define IQtoQ12(A) (long) ((A) * 4096.0f)
|
||||
|
||||
#define Q5toIQ(A) (((float) (A)) * 0.031250f)
|
||||
#define Q6toIQ(A) (((float) (A)) * 0.015625f)
|
||||
|
||||
#define ONEbySQRT3 0.57735026918963 /* 1/sqrt(3) */
|
||||
|
||||
|
||||
#define ABS(x) ( ((x) >= 0) ? (x) : -(x) )
|
||||
#define FABS(x) ( ((x) >= 0.0f) ? (x) : -(x) )
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------------------
|
||||
*Îáú˙âëĺíč˙ ňčďîâ
|
||||
*----------------------------------------------------------------------------------------
|
||||
*/
|
||||
typedef float _iq;
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------------------
|
||||
*Îáú˙âëĺíč˙ ôóíęöčé
|
||||
*----------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------------------
|
||||
*Îďđĺäĺëĺíč˙ ăëîáŕëüíűő ďĺđĺěĺííűő
|
||||
*----------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#endif /* IQMATH_H_ */
|
||||
63
Projects/epwm_test/src/vector/pi.h
Normal file
63
Projects/epwm_test/src/vector/pi.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
*========================================================================================
|
||||
* (C) Copyright 2019 ÀÎ "Äèàêîíò"
|
||||
* ã. Ñàíêò-Ïåòåðáóðã, Ðîññèÿ
|
||||
*
|
||||
* Ôàéë: pi.h
|
||||
*
|
||||
*========================================================================================
|
||||
*/
|
||||
|
||||
#ifndef __PI_H__
|
||||
#define __PI_H__
|
||||
/*
|
||||
*----------------------------------------------------------------------------------------
|
||||
*Âêëþ÷àåìûå ôàéëû
|
||||
*----------------------------------------------------------------------------------------
|
||||
*/
|
||||
#include "iqmath.h"
|
||||
/*
|
||||
*----------------------------------------------------------------------------------------
|
||||
*Îáúÿâëåíèÿ ìàêðîñîâ
|
||||
*----------------------------------------------------------------------------------------
|
||||
*/
|
||||
/*------------------------------------------------------------------------------
|
||||
PI_GRANDO Macro Definition
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
#define PI_MACRO(v) \
|
||||
\
|
||||
/* proportional term */ \
|
||||
v.up = _IQmpy(v.Kp, (v.Ref - v.Fbk)); \
|
||||
\
|
||||
/* integral term */ \
|
||||
v.ui = (v.Out == v.v1)?(_IQmpy(v.Ki, v.up)+ v.i1) : v.i1; \
|
||||
v.i1 = v.ui; \
|
||||
\
|
||||
/* control output */ \
|
||||
v.v1 = v.up + v.ui + v.uCorr; \
|
||||
v.Out= _IQsat(v.v1, v.Umax, v.Umin); \
|
||||
/*
|
||||
*----------------------------------------------------------------------------------------
|
||||
*Îáúÿâëåíèÿ òèïîâ
|
||||
*----------------------------------------------------------------------------------------
|
||||
*/
|
||||
typedef struct {
|
||||
_iq Ref; // Input: reference set-point
|
||||
_iq Fbk; // Input: feedback
|
||||
_iq uCorr; // Input: Êîððåêöèÿ âûõîäà, äëÿ óñòðàíåíèÿ ïåðåêðåòíûõ ñâÿçåé
|
||||
_iq Out; // Output: controller output
|
||||
_iq Kp; // Parameter: proportional loop gain
|
||||
_iq Ki; // Parameter: integral gain
|
||||
_iq Umax; // Parameter: upper saturation limit
|
||||
_iq Umin; // Parameter: lower saturation limit
|
||||
_iq up; // Data: proportional term
|
||||
_iq ui; // Data: integral term
|
||||
_iq v1; // Data: pre-saturated controller output
|
||||
_iq i1; // Data: integrator storage: ui(k-1)
|
||||
} PI_CONTROLLER;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // __PI_H__
|
||||
79
Projects/epwm_test/src/vector/pid.h
Normal file
79
Projects/epwm_test/src/vector/pid.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
*========================================================================================
|
||||
* (C) Copyright 2019 ÀÎ "Äèàêîíò"
|
||||
* ã. Ñàíêò-Ïåòåðáóðã, Ðîññèÿ
|
||||
*
|
||||
* Ôàéë: pi.h
|
||||
* Îïèñàíèå: Ìîäóëü ÏÈÄ-ðåãóëÿòîðà
|
||||
*----------------------------------------------------------------------------------------
|
||||
* Èñòîðèÿ èçìåíåíèé:
|
||||
* íîìåð äàòà | Ôàìèëèÿ È.Î. | ÇÈ | Îïèñàíèå èçìåíåíèé
|
||||
*----------------------------------------------------------------------------------------
|
||||
* 001 | 24.01.19 | Ñû÷åâ Â.À. | 136 | Íà÷àëüíàÿ ðàçðàáîòêà
|
||||
* 002 | 10.03.21 | Ñû÷åâ Â.À. | 231 | Óäàëåíî ïîëå uCorr
|
||||
*========================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __PID_H__
|
||||
#define __PID_H__
|
||||
/*
|
||||
*----------------------------------------------------------------------------------------
|
||||
*Âêëþ÷àåìûå ôàéëû
|
||||
*----------------------------------------------------------------------------------------
|
||||
*/
|
||||
#include "iqmath.h"
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------------------
|
||||
*Îáúÿâëåíèÿ ìàêðîñîâ
|
||||
*----------------------------------------------------------------------------------------
|
||||
*/
|
||||
#define PID_RESET(PI) (PI.Fbk = PI.i1 = PI.v1 = PI.d1 = PI.Out = 0.0f)
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
PI_GRANDO Macro Definition
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
#define PID_MACRO(v) \
|
||||
\
|
||||
/* proportional term */ \
|
||||
v.up = _IQmpy(v.Kp, (v.Ref - v.Fbk)); \
|
||||
\
|
||||
/* integral term */ \
|
||||
v.ui = (v.Out == v.v1)?(_IQmpy(v.Ki, v.up)+ v.i1) : v.i1; \
|
||||
v.i1 = v.ui; \
|
||||
/* diff term*/ \
|
||||
v.ud = _IQmpy(v.Kd, (v.up - v.d1)); \
|
||||
v.d1 = v.up; \
|
||||
/* control output */ \
|
||||
v.v1 = v.up + v.ui + v.ud; \
|
||||
\
|
||||
v.Out= _IQsat(v.v1, v.Umax, v.Umin); \
|
||||
|
||||
#endif // __PID_H__
|
||||
/*
|
||||
*----------------------------------------------------------------------------------------
|
||||
*Îáúÿâëåíèÿ òèïîâ
|
||||
*----------------------------------------------------------------------------------------
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
_iq Ref; // Input: reference set-point
|
||||
_iq Fbk; // Input: feedback
|
||||
_iq Out; // Output: controller output
|
||||
_iq Kp; // Parameter: proportional loop gain
|
||||
_iq Ki; // Parameter: integral gain
|
||||
_iq Kd; // Diff gain
|
||||
_iq Umax; // Parameter: upper saturation limit
|
||||
_iq Umin; // Parameter: lower saturation limit
|
||||
_iq up; // Data: proportional term
|
||||
_iq ui; // Data: integral term
|
||||
_iq ud; // Diff term
|
||||
_iq v1; // Data: pre-saturated controller output
|
||||
_iq i1; // Data: integrator storage: ui(k-1)
|
||||
_iq d1; // Diff storage
|
||||
} TPid;
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user