mirror of
https://github.com/pvvx/RTL00MP3.git
synced 2025-03-19 11:32:58 +00:00
299 lines
8.6 KiB
C
299 lines
8.6 KiB
C
|
/*
|
||
|
* 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 <stdio.h>
|
||
|
#include <math.h>
|
||
|
#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<len;i++){ // Read 256 Bytes/Page to Flash Memory
|
||
|
SPI_PL7223_SEND(DUM_PL7223); // Send Dummy Data to Read righ Data
|
||
|
buf[i] = SPDAT; // Read SPIDAT and clear TX complete flag
|
||
|
}
|
||
|
|
||
|
gpio_write(&gpio_cs, 1);
|
||
|
|
||
|
}
|
||
|
//--------------------------------------------------------------------------------------------//
|
||
|
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
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
//--------------------------------------------------------------------------------------------//
|
||
|
|
||
|
|