/* * Routines to access hardware * * Copyright (c) 2015 Realtek Semiconductor Corp. * * This module is a confidential and proprietary property of RealTek and * possession or use of this module requires written permission of RealTek. */ #include #include #include "device.h" #include "main.h" #include "spi_api.h" #include "gpio_api.h" // SPI0 #define SPI0_MOSI PC_2 #define SPI0_MISO PC_3 #define SPI0_SCLK PC_1 #define SPI0_CS PC_0 #define GPIO_RESET PB_4 #define GPIO_CS PB_5 //-------------------------------------------------------------------------------------------- #define READ_PL7223 0x4000 #define WRITE_PL7223 0x8000 #define DSPSTATUS_PL7223 0xF000 #define DUM_PL7223 0x00 //Dummy Data unsigned char SPDAT; // simulate example code unsigned char DSP_STATUS=0; unsigned char Read_Data_PL7223[146]; // Read_Data; 256Bytes=1Page unsigned char Write_Data_PL7223[146]; // Write_Data; 256Bytes=1Page unsigned char Cmd_RD=0; long EE_Temp = 0; float VA_rms=0; float IA_rms=0; float PA=0; float SA=0; float QA=0; float PF_A=0; float Theta_A=0; float Frequency=0; int Sample_cnt0=0; int ZCC_cnt=0; int ZCC_Start=0; int ZCC_Stop=0; void Initial_SPI_PL7223(void); void SPI_PL7223_SEND(unsigned char); void SPI__PL7223_Read_Status(void); void SPI_PL7223_DELY(int); void SPI_PL7223_Reset(void); void SPI_PL7223_Read(unsigned char*, unsigned int, unsigned int); void SPI_PL7223_Write(unsigned char*, unsigned int, unsigned int); void SPI_PL7223_Masurement(void); void SPI_PL7223_RelayControl(int); static spi_t spi0_master; static gpio_t gpio_reset; static gpio_t gpio_cs; /** * @brief Main program. * @param None * @retval None */ void main(void) { gpio_init(&gpio_reset, GPIO_RESET); gpio_mode(&gpio_reset, PullUp); gpio_dir(&gpio_reset, PIN_OUTPUT); gpio_init(&gpio_cs, GPIO_CS); gpio_mode(&gpio_cs, PullUp); gpio_dir(&gpio_cs, PIN_OUTPUT); spi_init(&spi0_master, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS); spi_format(&spi0_master, 8, 3, 0); spi_frequency(&spi0_master, 800000); do { SPI_PL7223_Reset(); SPI_PL7223_Read(&Read_Data_PL7223[0],0x3860,1);//DSP version :20130322 ver02, 0x3860=0x04 //DSP version :20141009 ver01, 0x3860=0x03 }while( ((Read_Data_PL7223[0]) != 0x04) && ((Read_Data_PL7223[0]) != 0x03) ); SPI_PL7223_DELY(120000); SPI_PL7223_RelayControl(0); // OFF SPI_PL7223_DELY(120000); do{ // As below is read DSP buffer process every time (144 byte) SPI__PL7223_Read_Status(); SPI_PL7223_Read(&Read_Data_PL7223[0],0x3000,144); // 0x3000~0x308F //144 byte SPI_PL7223_Read(&Read_Data_PL7223[144],0x3809,2); // Sample_cnt0 SPI_PL7223_Masurement(); SPI_PL7223_DELY(600000); SPI_PL7223_RelayControl(1); // ON SPI_PL7223_DELY(120000); SPI__PL7223_Read_Status(); SPI_PL7223_Read(&Read_Data_PL7223[0],0x3000,144); // 0x3000~0x308F //144 byte SPI_PL7223_Read(&Read_Data_PL7223[144],0x3809,2); // Sample_cnt0 SPI_PL7223_Masurement(); SPI_PL7223_DELY(600000); SPI_PL7223_RelayControl(0); // OFF SPI_PL7223_DELY(120000); }while(1); } //--------------------------------------------------------------------------------------------// void SPI_PL7223_RelayControl(int sw) { #define RELAY_MASK (1<<5) SPI_PL7223_Read(&Read_Data_PL7223[0],0x380F,1); if(!sw) Read_Data_PL7223[0] &= (~RELAY_MASK); else Read_Data_PL7223[0] |= RELAY_MASK; SPI_PL7223_Write(&Read_Data_PL7223[0],0x380F,1); } //--------------------------------------------------------------------------------------------// void SPI_PL7223_Reset(void) { gpio_write(&gpio_cs, 0); SPI_PL7223_DELY(500); //need delay 10ms gpio_write(&gpio_reset, 1); SPI_PL7223_DELY(500); //need delay 10ms gpio_write(&gpio_reset, 0); SPI_PL7223_DELY(500); //need delay 10ms gpio_write(&gpio_reset, 1); SPI_PL7223_DELY(500); //need delay 10ms gpio_write(&gpio_cs, 1); SPI_PL7223_DELY(300); } //--------------------------------------------------------------------------------------------// void SPI__PL7223_Read_Status(void) { gpio_write(&gpio_cs, 0); SPI_PL7223_SEND((unsigned char)(DSPSTATUS_PL7223 >> 8)& 0xFF); // RDSR command SPI_PL7223_SEND((unsigned char)(DSPSTATUS_PL7223& 0x00FF)); // RDSR command //check DSP flag state (byte) do { SPI_PL7223_SEND(DUM_PL7223); DSP_STATUS=SPDAT; }while((DSP_STATUS & 0x80) == 0x00); // Bit7=1 is Ready gpio_write(&gpio_cs, 1); } //--------------------------------------------------------------------------------------------// void SPI_PL7223_Write(unsigned char* buf, unsigned int addr, unsigned int len) { unsigned int i; gpio_write(&gpio_cs, 0); addr |= WRITE_PL7223; // Write command SPI_PL7223_SEND((unsigned char)(addr >> 8)& 0xFF); // Write middle byte address SPI_PL7223_SEND((unsigned char)(addr & 0xFF));// Write low byte address for (i = 0; i < len ; i++){ SPI_PL7223_SEND(buf[i]); } gpio_write(&gpio_cs, 1); SPI_PL7223_DELY(3); // for CS:Hi to Low need 100nsec, Delay-Time 27usec } //--------------------------------------------------------------------------------------------// void SPI_PL7223_Read(unsigned char* buf, unsigned int addr, unsigned int len) { static unsigned int i; gpio_write(&gpio_cs, 0); addr |= READ_PL7223; // Read command SPI_PL7223_SEND((unsigned char)(addr >> 8)& 0xFF); // Write middle byte address SPI_PL7223_SEND((unsigned char)(addr & 0x00FF)); // Write low byte address for(i=0;i> 8)& 0xFF); // RDSR command SPI_PL7223_SEND((unsigned char)(DSPSTATUS_PL7223& 0x00FF)); // RDSR command do { SPI_PL7223_SEND(DUM_PL7223); DSP_STATUS=SPDAT; }while((DSP_STATUS & 0x80) == 0x00); // Bit7=1 is Ready gpio_write(&gpio_cs, 1); } //--------------------------------------------------------------------------------------------// void SPI_PL7223_Masurement(void) { //Vrms address : 0x3002~0x3003 // VA_rms = (Read_Data_PL7223[3]*256+Read_Data_PL7223[2])/64; EE_Temp = Read_Data_PL7223[3]; EE_Temp = EE_Temp << 8; EE_Temp += Read_Data_PL7223[2]; VA_rms = (float)EE_Temp/64.00; //Irms address : 0x3008~0x3009 // IA_rms = Read_Data_PL7223[3]+Read_Data_PL7223[2]/256; EE_Temp = Read_Data_PL7223[8]; IA_rms = (float)EE_Temp/256.00; EE_Temp = Read_Data_PL7223[9]; IA_rms = IA_rms + (float)EE_Temp; //Active address : 0x3078~0x307D // PA = Read_Data_PL7223[124]*256+Read_Data_PL7223[123]; EE_Temp = Read_Data_PL7223[124]; EE_Temp = EE_Temp << 8; EE_Temp += Read_Data_PL7223[123]; PA = (float)EE_Temp; //PF Calculate // SA = VA_rms*IA_rms; SA = VA_rms*IA_rms; // PF_A = PA/SA PF_A = SA==0? 0: PA/SA; Theta_A = acos(PF_A); QA = SA * sin(Theta_A); if(IA_rms==0) Theta_A = 0; else Theta_A = Theta_A * (180.00/(3.141592653589)); /** Frequency = [Sample_cnt0/(ZCC_STOP-ZCC_START)]*[(ZCC_CNT-1)/2] */ Sample_cnt0 = Read_Data_PL7223[145]; // Sample_cnt01 Sample_cnt0 = Sample_cnt0 <<8; Sample_cnt0 += Read_Data_PL7223[144]; // Sample_cnt00 ZCC_cnt = Read_Data_PL7223[91]; // ZCC_cnt1 ZCC_cnt = ZCC_cnt <<8; ZCC_cnt += Read_Data_PL7223[90]; // ZCC_cnt0 ZCC_Stop = Read_Data_PL7223[97]; // ZCC_STOP1 ZCC_Stop = ZCC_Stop <<8; ZCC_Stop += Read_Data_PL7223[96]; // ZCC_STOP0 ZCC_Start = Read_Data_PL7223[103]; // ZCC_START1 ZCC_Start = ZCC_Start <<8; ZCC_Start += Read_Data_PL7223[102]; // ZCC_START0 Frequency = (float)((float)Sample_cnt0 / (ZCC_Stop - ZCC_Start)) * (((float)ZCC_cnt - 1.0) / 2); #define UART_Display(name) printf(#name" %d.%d\n\r", (int)(name*1000)/1000, (int)(name*1000)%1000) UART_Display(VA_rms); UART_Display(IA_rms); UART_Display(Frequency); UART_Display(PA); UART_Display(QA); UART_Display(SA); UART_Display(PF_A); UART_Display(Theta_A); } //--------------------------------------------------------------------------------------------// void SPI_PL7223_DELY(int dely_cnt) // MCUCLK 4MHz, Delay-Time 9usec/clock { HalDelayUs(dely_cnt*20); } //--------------------------------------------------------------------------------------------// void SPI_PL7223_SEND(unsigned char spicmd) { SPDAT = (char)spi_master_write(&spi0_master, (int)spicmd); } //--------------------------------------------------------------------------------------------//