I had removed the jumper to make the reset button easier to press (as you suggested), but I had installed a wire (as someone somewhere else suggested...)
Are there any communities that talk about programming the STM32 chips without the ST Peripheral Library? I've been trying to get the USART working (in asm), without much luck. The thread through the plib is hopelessly obscured compared to what I have in mind, so it's not very useful. I've got: UARTInit:
/*
* Uart1 is on Port A9/A10
* First Turn on clock for port A, including Alternate Functions, and UART
* rcc->apb2enr = iopaen|afioen|usart1en ;
*/
bx lr
ldr r0, =RCC_BASE
ldr r1, [r0, #RCC_APB2ENR] /* old val */
orr r1, #RCC_APB2ENR_IOPAEN|RCC_APB2ENR_AFIOEN /* enable PORTA, AltFunc clk */
str r1, [r0, #RCC_APB2ENR]
orr r1, #RCC_APB2ENR_USART1EN
str r1, [r0, #RCC_APB2ENR]
ldr r1, [r0, #RCC_APB2RSTR]
orr r1,r2, #RCC_APB2RSTR_USART1RST
bic r1, #RCC_APB2RSTR_USART1RST
str r2, [r0, #RCC_APB2RSTR] /* Reset the UART */
nop
nop
str r1, [r0, #RCC_APB2RSTR] /* Un-reset */
nop
nop
/*
* Set the pins appropriately (A9 as alt function output, A10 default to input)
*/
ldr r0, =GPIOA_BASE /* GPIO_PORTA */
ldr r1, [r0, #GPIO_CRH]
bic r1, ( (0xF << ((9-8)*4)) | (0xF << ((10-8)*4)) )
orr r1, #((GPIO_MODE_OUT50MHz+GPIO_CNF_AFPP) << ((9-8)*4)) /* output bit */
orr r1, #((GPIO_MODE_IN+GPIO_CNF_FLOAT) << ((10-8)*4)) /* input bit */
str r1, [r0, #GPIO_CRH] /* set io bit modes */
/*
* Set up the USART itself
*/
ldr r0, =USART1_BASE
ldr r1, =F_CPU/115200
str.w r1, [r0, #USART_BRR]
mov r1, #USART_CR1_TE+USART_CR1_RE /* Enable TX and RX */
str.w r1, [r0, #USART_CR1]
orr r1, #USART_CR1_UE /* Enable USART as a whole */
str.w r1, [r0, #USART_CR1]
/* CR2 and CR2 are OK at their default values */
mov r1, #'I' /* Initial test character */
str.w r1, [r0, #USART_DR]
bx lr
And let me take this opportunity to flame some more at the ST people. Their explanation of the fractional baud rate divisor is ... awful - like it was written by someone who doesn't understand math. And the library follows suit, doing weird math like: integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate)));
tmpreg = (integerdivider / 100) << 4;
/* Determine the fractional part */
fractionaldivider = integerdivider - (100 * (tmpreg >> 4));
/* Implement the fractional part in the register */
tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);
/* Write to USART BRR */
USARTx->BRR = (uint16_t)tmpreg;
Whereas I claim (and have tested, on a desktop) that you can just do:USARTx->BRR = apbclock/baudrate;
Because they say that divisor = CLK/(16*Baud), and then convert the integer and fraction parts to nybbles in the BRR separately, but since the fraction needs to be in 16ths anyway, CLK/Baud already puts the same bits in the correct place. Grr.
Maybe I should take the opportunity to complain about deriving the current clock rate from the internal state of the chip (but ultimately based on properly defining the crystal clock rate) instead of just #defining it, but I guess that makes SOME sense, what with the possibility of changing clock rates/etc for possible power saving reasons...
(In general, the pieces of the peripheral library that I've looked at SEEM like they were carefully written to be inline functions off in a .h file somewhere, which would cause a lot of the ickier looking code to optimize away and end up pretty reasonable. And then maybe some higher-level manager came along and said "We can't have C code in .h files! It's against the xyz standard policy! Move it all into separately compilable library modules immediately!" Sigh.)