STM32H750 receives an addition zero in RXDR register in SPI receive only mode.
Hello having a bit of a problem and was wondering if anyone here could spot what I am doing wrong.
I am interfacing to an Analog device part ADE7878 using HSDC interface. The datasheet for this device can be found here http://www.autex.spb.su/ad/ADE7878.pdf
Data sent from the ADE7878 is enclosed in an active low SS/HSA signal cycle.
The problem I am experiencing is that on the first ever capture I can see that
all 16 32-bit register sent by the ADE7878 are caputured by the STM32H750
and consistent with the trace from the logic analyser.
From the second capture cycle onward the first register always reads as zero and
and then the data from the ADE registers.
Example
Cycle 1
Logic Analyser: a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p
STM32 reads: a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p
Cycle 2 (onward)
Logic Analyser: a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p
STM32 reads: 0,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o
Any suggestions on what configuration needs changing. I can find a work around
by swallowing the first capture and read the last register in the
"if ( (isr & SPI_SR_EOT ) == SPI_SR_EOT )" block but I don't find this very neat
any suggestions is well come.
Below is the code snippet of what I am doing
#define HSDC_MAX_REG 16
#define MAX_TRACE_ENTRY 100
extern SPI_HandleTypeDef hspi2;
typedef struct hsdc_registers_struct
{
uint32_t IAWV, VAWV, IBWV, VBWV, ICWV, VCWV, INWV, AVA,
BVA, CVA, AWATT, BWATT, CWATT, AVAR, BVAR, CVAR;
}hsdc_registers_t;
class HSDC;
{
public:
int size(); // returns the number of item in the buf
void insert(hsdc_registers_t* src); // insert an item in the buf
void extract(hsdc_registers_t* dst);// extracts an item from the buffer
private:
hsdc_registers_t buf[MAX_TRACE_ENTRY];
int rear,front,count;
}
HSDC hsdc;
void thread()
{
SPI2_InterruptEnable();
while (1)
{
if (hsdc.size())
{
hsdc_registers_t hsdc_registers;
hsdc.extract(&hsdc_registers);
HAL_UART_Transmit(&huart3, (uint8_t*)&hsdc_registers, sizeof (hsdc_registers_t), HAL_MAX_DELAY);
}
}
}
void SPI2_InterruptEnable()
{
MODIFY_REG(hspi2.Instance->CR2, SPI_CR2_TSIZE, HSDC_MAX_REG);
__HAL_SPI_ENABLE(&hspi2);
__HAL_SPI_ENABLE_IT(&hspi2,
(SPI_IT_EOT | SPI_IT_RXP | SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF | SPI_IT_TSERF));
}
void SPI2_IRQHandler(void)
{
static int count = 0;
static uint32_t rxbuf[HSDC_MAX_REG];
SPI_TypeDef* instance = hspi2.Instance;
uint32_t isr = instance->SR;
if ( (isr & SPI_SR_EOT ) == SPI_SR_EOT )
{
hsdc.insert((hsdc_registers_t*)rxbuf);
instance->IFCR |= SPI_FLAG_EOT;
count = 0;
}
if ( (isr & SPI_SR_TXTF ) == SPI_SR_TXTF )
{
instance->IFCR |= SPI_FLAG_TXTF;
}
if ( (isr & SPI_SR_UDR ) == SPI_SR_UDR )
{
instance->IFCR |= SPI_FLAG_UDR;
}
if ( (isr & SPI_SR_OVR ) == SPI_SR_OVR )
{
instance->IFCR |= SPI_FLAG_OVR;
}
if ( (isr & SPI_SR_TIFRE ) == SPI_SR_TIFRE )
{
instance->IFCR |= SPI_FLAG_FRE;
}
if ( (isr & SPI_SR_MODF ) == SPI_SR_MODF )
{
instance->IFCR |= SPI_FLAG_MODF;
}
if ( (isr & SPI_SR_TSERF ) == SPI_SR_TSERF )
{
instance->IFCR |= SPI_FLAG_TSERF;
}
if ( (isr & SPI_SR_SUSP ) == SPI_SR_SUSP )
{
instance->IFCR |= SPI_FLAG_SUSP;
}
if ( (isr & SPI_SR_RXP ) == SPI_SR_RXP )
{
rxbuf[count++] = instance->RXDR;
}
}