I have a cascade of 4 8x8 matrices working via max7219. I use stm32 f103 for send commands to the cascade. For some reason when I send CommandN, CommandN-1 performs.
Here's my code
int main(void)
{
clockInit();
SysTick_Init(72000000);
initSwdOnlyDebugging();
initPortAClock();
initAltFunctionsClock();
initSpi1();
for (int i = 0; i < 4; ++i)
{
sendData(OperationCode::OP_DISPLAYTEST, 0x00);
}
...
}
void sendData(uint8_t address, uint8_t data)
{
GPIOA->BSRR = 1 << 4; // CS SET (PA4)
while(!(READ_BIT(SPI1->SR, SPI_SR_TXE) == (SPI_SR_TXE))) {}
SPI1->DR = address;
while(!(READ_BIT(SPI1->SR, SPI_SR_RXNE) == (SPI_SR_RXNE))) {}
(void) SPI1->DR;
while(!(READ_BIT(SPI1->SR, SPI_SR_TXE) == (SPI_SR_TXE))) {}
SPI1->DR = data;
while(!(READ_BIT(SPI1->SR, SPI_SR_RXNE) == (SPI_SR_RXNE))) {}
(void) SPI1->DR;
GPIOA->BSRR = 1 << 4 << 16U; // CS RESET (PA4)
}
enum OperationCode: uint8_t
{
OP_DECODEMODE = 9, ///< MAX72xx opcode for DECODE MODE
OP_INTENSITY = 10, ///< MAX72xx opcode for SET INTENSITY
OP_SCANLIMIT = 11, ///< MAX72xx opcode for SCAN LIMIT
OP_SHUTDOWN = 12, ///< MAX72xx opcode for SHUT DOWN
OP_DISPLAYTEST = 15 ///< MAX72xx opcode for DISPLAY TEST
};
int clockInit(void)
{
// RCC - reset and clock control, CR - Clock control register
SET_BIT(RCC->CR, RCC_CR_HSEON); //Enable HSE clock
while(READ_BIT(RCC->CR, RCC_CR_HSERDY) == RESET); //wait until HSE ready
//Configuring of PLL (HSE crystal frequency is 8MHz)
// SYSCLK = 72 МГц, USB = 48 МГц, PCLK1 = 36 МГц, PCLK2 = 72 МГц, ADC = 12 МГц
RCC->CFGR |= RCC_CFGR_PLLMULL9 //Bits 21:18, 0111: PLL input clock x 9
| RCC_CFGR_PLLSRC; //Enable PLL as a source of HSE
RCC->CR |= RCC_CR_PLLON; //Run PLL
while(!(RCC->CR & RCC_CR_PLLRDY));
CLEAR_BIT(FLASH->ACR, FLASH_ACR_PRFTBE);
FLASH->ACR |= FLASH_ACR_PRFTBE;
// 2 cycles of Flash wait because 48 MHz < SYSCLK ≤ 72 MHz
FLASH->ACR &= ~FLASH_ACR_LATENCY_2;
FLASH->ACR |= FLASH_ACR_LATENCY_2;
RCC->CFGR |= RCC_CFGR_PPRE2_DIV1 //APB2/1
| RCC_CFGR_PPRE1_DIV2 //APB1/2
| RCC_CFGR_HPRE_DIV1; //AHB/1
RCC->CFGR |= RCC_CFGR_SW_PLL;
while((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_1);
RCC->CR &= ~RCC_CR_HSION;
return 0;
}
void initSpi1(void)
{
auto reg = GPIOA->CRL;
reg &= ~(GPIO_CRL_CNF4 | GPIO_CRL_MODE4 | GPIO_CRL_CNF5 | GPIO_CRL_MODE5 | GPIO_CRL_CNF6 | GPIO_CRL_MODE6 | GPIO_CRL_CNF7 | GPIO_CRL_MODE7);
GPIOA->CRL = reg;
GPIOA->CRL |= GPIO_CRL_MODE7; // output 50 MHz
GPIOA->CRL &= ~GPIO_CRL_CNF7; // Push-Pull
GPIOA->CRL |= GPIO_CRL_CNF7_1; // alternative function push-pull
GPIOA->CRL &= ~GPIO_CRL_MODE6; // Input
GPIOA->CRL |= GPIO_CRL_CNF6_1; // with pull-up / pull-down
GPIOA->BSRR = GPIO_BSRR_BS6; // Set bit 6 High
GPIOA->CRL |= GPIO_CRL_MODE5; // output 50 MHz
GPIOA->CRL |= GPIO_CRL_CNF5_1; // alternative function push-pull
GPIOA->CRL |= GPIO_CRL_MODE4; // output 50 MHz
GPIOA->CRL &= ~GPIO_CRL_CNF4; // Push-Pull General Purpose
GPIOA->BSRR = GPIO_BSRR_BS4; // Set bit 4 High
SPI1->CR1 = 0x0000; // reset SPI configuration registers
SPI1->CR2 = 0x0000; // reset SPI configuration registers
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // enable spi clock
SPI1->CR1 &= ~SPI_CR1_SPE; // disable SPI before configuring
SPI1->CR1 = 0 << SPI_CR1_DFF_Pos // 8 bit Data frame format
| 0 << SPI_CR1_LSBFIRST_Pos // MSB transferred first
| SPI_CR1_SSM //Software SS
| SPI_CR1_SSI // NSS (CS) pin is high
| SPI_CR1_BR_0 | SPI_CR1_BR_1 //Baud: F_PCLK/16
| SPI_CR1_MSTR // Master mode
| 0 << SPI_CR1_CPOL_Pos // Clock polarity
| 0 << SPI_CR1_CPHA_Pos; // Clock phase
SPI1->CR1 |= SPI_CR1_SPE; // Enable SPI
}
void initPortAClock()
{
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
}
void initSwdOnlyDebugging()
{
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // JTAG is disabled
}
void initAltFunctionsClock()
{
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
}
After the loop
for (int i = 0; i < 4; ++i)
{
sendData(OperationCode::OP_DISPLAYTEST, 0x00);
}
finishes I have the first 3 matrices turned off, not all 4.