2024-10-04 07:11 AM
Hello!
I am trying to enable SPI communication through the SPI3 interface on an STM32F103ZFH6. I am aware that pins PA15 and PB3 are used for JTAG and SWJ, but I have disabled both using:
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
There is no clock signal on SPI3_SCK (PB3) and the pin is always low, as confirmed by using a logic analyzer. The SPI3_NSS pins work, after disabling JTAG though.
I am certain that the SPI settings, clock, and initialization are correct because data is being sent on the MOSI line, and the NSS pin is manually pulled down correctly during communication, just the clock signal is missing. GPIO settings are also correct as the SCK pin is set to GPIO_Mode_AF_PP.
I have also probed for continuity on the PCB and everything is correct. There is a series resistor on the MOSI, MISO, and SCK lines.
I have added a screenshot of the logic analyzer output I get. Currently, I think the issue may be a hardware issue in the microcontroller itself, but I am not sure how likely that is.
Any help or recommendations are appreciated!
Solved! Go to Solution.
2024-10-04 01:59 PM - edited 2024-10-04 02:00 PM
This means the pin state at the microcontroller is working correctly. If your logic analyzer isn't registering the high/low states, it's not connected to the pin. Check your wiring between the two. Perhaps a bad soldering job somewhere, or a mismatched cable.
It's a hardware or test setup problem, not a software one.
2024-10-04 07:30 AM
Initialize the pin as GPIO output and toggle it and verify that you can see the output on your logic analyzer. That will confirm if there is a hardware issue.
2024-10-04 10:23 AM - edited 2024-10-04 10:25 AM
You have to disable the JTAG functionality on PB3 in AFIO.
JW
2024-10-04 10:52 AM
I changed the GPIO_Mode of the SCK pin and I am toggling it like this in the "Iterate" function. No difference, I cannot manually toggle the PB3 pin.
#define SC16_SCK_PORT GPIOB
#define SC16_SCK_PIN GPIO_Pin_3
void GPIO_Initialize_OutPort (GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,
GPIOSpeed_TypeDef GPIO_Speed, GPIOMode_TypeDef GPIO_Mode, BitAction initial_state)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode;
GPIO_WriteBit(GPIOx, GPIO_Pin, initial_state);
GPIO_Init(GPIOx, &GPIO_InitStructure);
}
GPIO_Initialize_OutPort(SC16_SCK_PORT, SC16_SCK_PIN,
GPIO_Speed_50MHz, GPIO_Mode_Out_PP, Bit_RESET);
static void Iterate() {
GPIO_WriteBit(SC16_SCK_PORT, SC16_SCK_PIN, Bit_RESET);
for(int u; u < 0x8000; u++); // Delay
GPIO_WriteBit(SC16_SCK_PORT, SC16_SCK_PIN, Bit_SET);
}
2024-10-04 10:56 AM
I am already disabling the JTAG functionality. As I said above, disabling JTAG made it so that I can use PA15 as a manual CS pin, but PB3 still is not working. Even if I disable SWJ aswell.
/*!< SWJ_CFG configuration */
#define AFIO_MAPR_SWJ_CFG_Pos (24U)
#define AFIO_MAPR_SWJ_CFG_Msk (0x7UL << AFIO_MAPR_SWJ_CFG_Pos) /*!< 0x07000000 */
#define AFIO_MAPR_SWJ_CFG AFIO_MAPR_SWJ_CFG_Msk /*!< SWJ_CFG[2:0] bits (Serial Wire JTAG configuration) */
#define AFIO_MAPR_SWJ_CFG_DISABLE_Pos (26U)
#define AFIO_MAPR_SWJ_CFG_DISABLE_Msk (0x1UL << AFIO_MAPR_SWJ_CFG_DISABLE_Pos) /*!< 0x04000000 */
#define AFIO_MAPR_SWJ_CFG_DISABLE AFIO_MAPR_SWJ_CFG_DISABLE_Msk /*!< JTAG-DP Disabled and SW-DP Disabled */
#define AFIO_DBGAFR_CONFIG(DBGAFR_SWJCFG) do{ uint32_t tmpreg = AFIO->MAPR; \
tmpreg &= ~AFIO_MAPR_SWJ_CFG_Msk; \
tmpreg |= DBGAFR_SWJCFG; \
AFIO->MAPR = tmpreg; \
}while(0u)
AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_DISABLE);
2024-10-04 11:31 AM - edited 2024-10-04 11:31 AM
Is GPIOB clock enabled?
> I changed the GPIO_Mode of the SCK pin and I am toggling it like this in the "Iterate" function. No difference, I cannot manually toggle the PB3 pin.
Then it's probably not hooked up to what you think it's hooked up to.
If you really want to check further, debug your code that toggles the chip and example the GPIOB->IDR register. It should toggle when the ODR register gets updated. If it doesn't, the pin might be shorted to ground externally.
Your toggle/delay loop leaves something to be desired. Could be going through that fast enough that you don't notice it. Consider toggling it indefinitely rather than just once. No clues here how you're calling Iterate().
while (1) {
GPIO_WriteBit(SC16_SCK_PORT, SC16_SCK_PIN, Bit_RESET);
GPIO_WriteBit(SC16_SCK_PORT, SC16_SCK_PIN, Bit_SET);
}
I don't think there's anything special about PB3 other than the SWD function.
2024-10-04 11:40 AM
Hi,
Just: why dont you use Cube/HAL , to see "how its done" ?
(Even if you dont like it ... )
2024-10-04 11:56 AM
All GPIO clocks A-G are enabled, AF clock is enabled as well.
I checked GPIOB->IDR and GPIOB->ODR after setting PB3 to RESET(0) and after SET(1).
I got, after setting PB3 to low:
GPIOB->IDR[3] = 0
GPIOB->ODR[3] = 0
and after setting PB3 high:
GPIOB->IDR[3] = 1
GPIOB->ODR[3] = 1
2024-10-04 11:58 AM
I used CUBE to generate SPI3 code, but I didn't see anything I am not doing. I am using the exact same modes and speeds, enabling all necessary clocks and disabling JTAG and SWJ. Only thing I noticed that seemed odd was that I2C1 was indicated to conflict with SPI3, which I did not see any reference manual. Just to be save I also disabled I2C1 usage in my program, still no luck.
2024-10-04 12:38 PM
So just try: write a simple loop send-to-spi-something and check on the pins: ok or not.