2020-08-07 12:08 AM
I am trying to transmit through SPI to a MAX7219 chip on my STM32F412G-Discovery board. The system clock is running at 100 MHz. I am using a level shifter to handle the 3.3V -> 5V voltage changing. I have used this IC on an arduino so I do know it works.
I am trying to transmit through HAL_SPI_Transmit and manually controlling the CS line through GPIO.
I am transmitting SPI with this code:
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
uint16_t spiData = 0x0C00;
HAL_SPI_Transmit(&hspi1, &spiData, 1, HAL_MAX_DELAY);
while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
spiData = 0x0C01;
HAL_SPI_Transmit(&hspi1, &spiData, 1, HAL_MAX_DELAY);
while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
spiData = 0x0900;
HAL_SPI_Transmit(&hspi1, &spiData, 1, HAL_MAX_DELAY);
while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
spiData = 0x0303;
HAL_SPI_Transmit(&hspi1, &spiData, 1, HAL_MAX_DELAY);
while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
PA4 -> CS (set up as manual GPIO)
PA5 -> SCK
PA7 -> MOSI
My SPI1 init code is:
static void MX_SPI1_Init(void)
{
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
I checked my logic analyzer and all the waves looked fine. I feel like I am probably missing something simple that's going to make me feel stupid.
Solved! Go to Solution.
2020-08-07 03:43 PM
I appreciate your help. Thanks a lot.
I have it working now.
The issue was that the clock has to go high after each packet. I may have also been sending the wrong packets for it to work.
To work with an 8x8 LED matrix, I sent the following packets:
Display test 0x0F00
Scan Limit 0x0B07
Intensity 0x0A07
Decode Mode 0x0900
Clear all the LEDs in the display 0x0i00 where i is an integer from 1 to 8 inclusive
Display Off 0x0C00
Display On 0x0C01
Then output your LEDs. I tried the 4 corner points and sent:
0x0181
0x0881
2020-08-07 07:06 AM
You don't state what the problem is.
> uint16_t spiData = 0x0C00;
> HAL_SPI_Transmit(&hspi1, &spiData, 1, HAL_MAX_DELAY);
You're sending 1 byte (0x00) of a 2-byte value (0x00 0x0C). Is that intentional?
Actually, pretty sure the code as written won't compile, since you're passing a (uint16_t *) value instead of a (uint8_t *).
2020-08-07 10:00 AM
The problem is that the MAX7219 chip doesn't work (change state at all). I've tried several of the LED displays I have with this chip and none work. It doesn't even turn on or accept any of the commands, it seems. I tested the same commands on an Arduino SPI and it worked fine. So it's something I am doing wrong with the SPI on this STM32 chip.
The example compiles and if I write 2 as an argument instead of 1, then it outputs 32 bits instead of 16. I have verified that with both a logic analyzer and oscilloscope.
The example below shows where I send 1 byte. The clock pulses 16 times and it does send the full packet each time.
If I change it to 2 bytes, then I get 32 clock pulses and it sends invalid data.
2020-08-07 10:33 AM
According to this post here: https://community.st.com/s/question/0D50X00009kKdg5/halspitransmit-size-is-it-defined-as-a-byte-or-a-word, it looks like that byte is unit counts. So since I have the SPI_DATASIZE_16BIT defined, it is a word count which makes sense according to my post below with the waveforms.
2020-08-07 10:54 AM
> it looks like that byte is unit counts. So since I have the SPI_DATASIZE_16BIT defined, it is a word count which makes sense according to my post below with the waveforms.
Agreed. I missed that.
> So it's something I am doing wrong with the SPI on this STM32 chip.
Your SCK line should be idle low according to the datasheet, but the logic analyzer shows it high as you lower CS for the first time. Transmit a dummy byte with CS high first to get it into the correct state, then do CS low and send the commands you care about.
Data should be latched on the rising edge according to the datasheet. Your logic analyzer is latching data on the falling edge.
2020-08-07 11:26 AM
I tried that but it seems to have no effect. The latching issue seems to have been from the clock not being low when CS goes low.
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
uint16_t dummyData = 0x0101;
HAL_SPI_Transmit(&hspi1, &dummyData, 1, HAL_MAX_DELAY);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
uint16_t spiData = 0x0C00;
HAL_SPI_Transmit(&hspi1, &spiData, 1, HAL_MAX_DELAY);
while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
spiData = 0x0C01;
HAL_SPI_Transmit(&hspi1, &spiData, 1, HAL_MAX_DELAY);
while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
spiData = 0x0900;
HAL_SPI_Transmit(&hspi1, &spiData, 1, HAL_MAX_DELAY);
while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
spiData = 0x0303;
HAL_SPI_Transmit(&hspi1, &spiData, 1, HAL_MAX_DELAY);
while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
2020-08-07 11:39 AM
2020-08-07 03:43 PM
I appreciate your help. Thanks a lot.
I have it working now.
The issue was that the clock has to go high after each packet. I may have also been sending the wrong packets for it to work.
To work with an 8x8 LED matrix, I sent the following packets:
Display test 0x0F00
Scan Limit 0x0B07
Intensity 0x0A07
Decode Mode 0x0900
Clear all the LEDs in the display 0x0i00 where i is an integer from 1 to 8 inclusive
Display Off 0x0C00
Display On 0x0C01
Then output your LEDs. I tried the 4 corner points and sent:
0x0181
0x0881
2021-12-06 07:35 AM
Hi,
can your show me your code? It would be a nice inspiration, because I have a project, that is like this.
Thanks and best regards.