
STM32F103RC + IAR 6.30 + J-LINK
Использую SPI1, через пины PB3, PB4 и PB5. Основная функция PB3, это JTDO. А основная функция PB4, это NJTRST. Обе мне не нужны, поскольку работаю через Serial Wire. Что бы вывести на эти ноги сигналы SPI1, конфигурирую их как альтернативные и делаю remap:
Код
McuPinInit( BSP_PIN_ISM_CSn, MCU_PIN_MODE_OUT_GP_PP_10MHZ );
McuPinInit( BSP_PIN_ISM_SCK, MCU_PIN_MODE_OUT_AF_PP_10MHZ );
McuPinInit( BSP_PIN_ISM_SI, MCU_PIN_MODE_OUT_AF_PP_10MHZ );
McuPinInit( BSP_PIN_ISM_SO, MCU_PIN_MODE_OUT_AF_PP_10MHZ );
McuPinInit( BSP_PIN_ISM_GDO2, MCU_PIN_MODE_INP_FLOATING );
McuPinInit( BSP_PIN_ISM_GDO0, MCU_PIN_MODE_INP_FLOATING );
McuPioRemap( MCU_PIO_REMAP_SPI1_ENABLE );
//McuPioRemap( MCU_PIO_REMAP_SWJ_CFG_JTAG_DIS_SW_EN );
McuPioRemap( MCU_PIO_REMAP_SWJ_CFG_FULL_WITHOUT_NJTRST );
McuPinInit( BSP_PIN_ISM_SCK, MCU_PIN_MODE_OUT_AF_PP_10MHZ );
McuPinInit( BSP_PIN_ISM_SI, MCU_PIN_MODE_OUT_AF_PP_10MHZ );
McuPinInit( BSP_PIN_ISM_SO, MCU_PIN_MODE_OUT_AF_PP_10MHZ );
McuPinInit( BSP_PIN_ISM_GDO2, MCU_PIN_MODE_INP_FLOATING );
McuPinInit( BSP_PIN_ISM_GDO0, MCU_PIN_MODE_INP_FLOATING );
McuPioRemap( MCU_PIO_REMAP_SPI1_ENABLE );
//McuPioRemap( MCU_PIO_REMAP_SWJ_CFG_JTAG_DIS_SW_EN );
McuPioRemap( MCU_PIO_REMAP_SWJ_CFG_FULL_WITHOUT_NJTRST );
По конфигурации проблем нет, клок на GPIOx и AFIO включается в McuPinInit().
А вот с remap творится чертовщина. Ниже текст текущего варианта McuPioRemap(). Лишнее покоцал, но суть и так понятна:
CODE
typedef enum MCU_PIO_REMAP_e
{
MCU_PIO_REMAP_SWJ_CFG_FULL,
MCU_PIO_REMAP_SWJ_CFG_FULL_WITHOUT_NJTRST,
MCU_PIO_REMAP_SWJ_CFG_JTAG_DIS_SW_EN,
MCU_PIO_REMAP_SWJ_CFG_JTAG_DIS_SW_DIS,
...
MCU_PIO_REMAP_I2C1_DISABLE,
MCU_PIO_REMAP_I2C1_ENABLE,
MCU_PIO_REMAP_SPI1_DISABLE,
MCU_PIO_REMAP_SPI1_ENABLE
} MCU_PIO_REMAP;
////////////////////////////////////////////////////////////////////////////////
void McuPioRemap( MCU_PIO_REMAP Remap )
{
switch( Remap )
{
case MCU_PIO_REMAP_SWJ_CFG_FULL:
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_0;
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_1;
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_2;
break;
case MCU_PIO_REMAP_SWJ_CFG_FULL_WITHOUT_NJTRST:
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_0;
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_1;
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_2;
break;
case MCU_PIO_REMAP_SWJ_CFG_JTAG_DIS_SW_EN:
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_0;
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1;
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_2;
break;
case MCU_PIO_REMAP_SWJ_CFG_JTAG_DIS_SW_DIS:
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_0;
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_1;
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_2;
break;
...
case MCU_PIO_REMAP_I2C1_DISABLE:
AFIO->MAPR &= ~AFIO_MAPR_I2C1_REMAP;
break;
case MCU_PIO_REMAP_I2C1_ENABLE:
AFIO->MAPR |= AFIO_MAPR_I2C1_REMAP;
break;
case MCU_PIO_REMAP_SPI1_DISABLE:
AFIO->MAPR &= ~AFIO_MAPR_SPI1_REMAP;
break;
case MCU_PIO_REMAP_SPI1_ENABLE:
AFIO->MAPR |= AFIO_MAPR_SPI1_REMAP;
break;
default:
break;
}
}
{
MCU_PIO_REMAP_SWJ_CFG_FULL,
MCU_PIO_REMAP_SWJ_CFG_FULL_WITHOUT_NJTRST,
MCU_PIO_REMAP_SWJ_CFG_JTAG_DIS_SW_EN,
MCU_PIO_REMAP_SWJ_CFG_JTAG_DIS_SW_DIS,
...
MCU_PIO_REMAP_I2C1_DISABLE,
MCU_PIO_REMAP_I2C1_ENABLE,
MCU_PIO_REMAP_SPI1_DISABLE,
MCU_PIO_REMAP_SPI1_ENABLE
} MCU_PIO_REMAP;
////////////////////////////////////////////////////////////////////////////////
void McuPioRemap( MCU_PIO_REMAP Remap )
{
switch( Remap )
{
case MCU_PIO_REMAP_SWJ_CFG_FULL:
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_0;
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_1;
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_2;
break;
case MCU_PIO_REMAP_SWJ_CFG_FULL_WITHOUT_NJTRST:
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_0;
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_1;
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_2;
break;
case MCU_PIO_REMAP_SWJ_CFG_JTAG_DIS_SW_EN:
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_0;
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1;
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_2;
break;
case MCU_PIO_REMAP_SWJ_CFG_JTAG_DIS_SW_DIS:
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_0;
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_1;
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_2;
break;
...
case MCU_PIO_REMAP_I2C1_DISABLE:
AFIO->MAPR &= ~AFIO_MAPR_I2C1_REMAP;
break;
case MCU_PIO_REMAP_I2C1_ENABLE:
AFIO->MAPR |= AFIO_MAPR_I2C1_REMAP;
break;
case MCU_PIO_REMAP_SPI1_DISABLE:
AFIO->MAPR &= ~AFIO_MAPR_SPI1_REMAP;
break;
case MCU_PIO_REMAP_SPI1_ENABLE:
AFIO->MAPR |= AFIO_MAPR_SPI1_REMAP;
break;
default:
break;
}
}
Сначала у меня перестал откликаться SW, пришлось временно закомментить remap. Подумал, что либо сам ошибся, либо в <stm32f10x.h> косячёк в #define. Полез смотреть по шагам. Вижу вполне корректный ассемблер:
Код
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_0;
??McuPioRemap_4:
0x8000d40: 0xf8df 0x03f8 LDR.W R0, ??DataTable4_6; AFIO_MAPR
0x8000d44: 0x6801 LDR R1, [R0]
0x8000d46: 0xf041 0x7180 ORR.W R1, R1, #16777216; 0x1000000
0x8000d4a: 0x6001 STR R1, [R0]
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_1;
0x8000d4c: 0x6801 LDR R1, [R0]
0x8000d4e: 0xf021 0x7100 BIC.W R1, R1, #33554432; 0x2000000
0x8000d52: 0x6001 STR R1, [R0]
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_2;
0x8000d54: 0x6801 LDR R1, [R0]
0x8000d56: 0xf021 0x6180 BIC.W R1, R1, #67108864; 0x4000000
0x8000d5a: 0xe127 B.N ??McuPioRemap_3; 0x8000fac
...
??McuPioRemap_3:
0x8000fac: 0x6001 STR R1, [R0]
}
??McuPioRemap_4:
0x8000d40: 0xf8df 0x03f8 LDR.W R0, ??DataTable4_6; AFIO_MAPR
0x8000d44: 0x6801 LDR R1, [R0]
0x8000d46: 0xf041 0x7180 ORR.W R1, R1, #16777216; 0x1000000
0x8000d4a: 0x6001 STR R1, [R0]
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_1;
0x8000d4c: 0x6801 LDR R1, [R0]
0x8000d4e: 0xf021 0x7100 BIC.W R1, R1, #33554432; 0x2000000
0x8000d52: 0x6001 STR R1, [R0]
AFIO->MAPR &= ~AFIO_MAPR_SWJ_CFG_2;
0x8000d54: 0x6801 LDR R1, [R0]
0x8000d56: 0xf021 0x6180 BIC.W R1, R1, #67108864; 0x4000000
0x8000d5a: 0xe127 B.N ??McuPioRemap_3; 0x8000fac
...
??McuPioRemap_3:
0x8000fac: 0x6001 STR R1, [R0]
}
Когда дохожу до строки
0x8000d4a: 0x6001 STR R1, [R0]
в регистрах вижу корректные значения, в R1 значение 0x01000001, а в R0 адрес AFIO->MAPR ( 0x40010004 ).
Сразу после исполнения STR R1, [R0] в AFIO->MAPR вижу уже 0x02000001, вместо 0x01000001. Ну и на следующей инструкции, конечно, считывается как 0x02000001. Ну как-же так, доктор? Причем каждый из трех бит SWJ_CFG так же аккуратно сдвигается на единицу влево. А вот младшая 1, это remap SPI1, который был сделан ранее, причем этой же функцией. И ведь все корректно!
Нажмите для просмотра прикрепленного файла
P.S.
В еррате ничего похожего не нашел.