-
Notifications
You must be signed in to change notification settings - Fork 997
STM32F103XX UART implementation #107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Signed-off-by: Ron Evans <ron@hybridgroup.com>
Signed-off-by: Ron Evans <ron@hybridgroup.com>
src/machine/machine_stm32.go
Outdated
|
|
||
| type GPIOMode uint8 | ||
|
|
||
| const SystemClockSpeed = 72000000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
board_arduino.go uses CPU_FREQUENCY.
I think this is a better name for the constant, but it would be best to unify them. That can be done in a different PR, however.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually the system clock frequency, not the CPU frequency. That value could in theory change based on the user's clock register settings. 72Mhz is such as typical number used that it needed go be made into some kind of const, right? Maybe we need to have a more global group of consts with different common speed values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's exactly the difference between system clock and CPU frequency? Aren't they both just the CPU frequency?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The system clock at ARM can be based on several different sources, including the CPU freq. and can be changed at runtime.
The CPU frequency for AVR is set by fuses that can only be changed when flashing the chip and does not have another source for the system clock as far as I know.
If any change is called for to unify terms it might be to have AVR use the term SystemClockSpeed but probably not worth it, since typical AVR docs refer to this as CPU frequency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been looking into SystemClockSpeed a bit but it appears to be specific to CMSIS, and it doesn't seem to be used much. Looks like it is intended to easily communicate the current clock frequency across the system.
Cortex-M devices appear to be more flexible in their clock configurations, and can sometimes change the CPU frequency at runtime (like in the case of stm32, but not in the case of nrf). I think changing the frequency makes sense in some specific circumstances (like variable power sources), but in general I can't see a reason why you wouldn't want to run at the max clock speed at all times. By using a high CPU frequency, computations are faster to complete and the chip can go to sleep faster which saves energy.
Please correct me if I'm wrong, but in this light, the SystemClockSpeed global variable as used in CMSIS doesn't seem to make a lot of sense in the context of TinyGo. The only thing that is relevant is the (const) CPU frequency used on any particular configuration, which may depend on the board (whether there is a crystal available, for example). And thus it would be equivalent to CPU_FREQUENCY on the AVR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, changed.
src/machine/machine_stm32.go
Outdated
| func (p GPIO) getPort() *stm32.GPIO_Type { | ||
| // Also enable clock for that GPIO port. | ||
| // Do this always, as it isn't known whether the clock has already been | ||
| // enabled. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getPort is also used in Set, so the peripheral will be enabled every time a pin is toggled, which seems wasteful to me.
It's perhaps a little bit of duplication, but can you maybe move the switch to enable the peripheral into the Configure function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems like a good suggestion. I will do that.
src/machine/machine_stm32.go
Outdated
| // USART1 is the first hardware serial port on the STM32. | ||
| // Both UART0 and UART1 refers to USART1. | ||
| UART0 = &UART{} | ||
| UART1 = UART0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So there is no UART0 on the STM32?
It seems a bit wrong this way but I guess exposing UART0 for USART1 is the best thing to do here, then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Somewhat offtopic: I think it would be nice to not have UART0, UART1 etc. but just [...]UART at some point in the future, to also make it easier to enumerate UART devices, for example in periph. That means the first UART is always UART[0]. This is even more relevant to other peripherals like I2C, especially on chips that don't have fixed pins for peripherals.
src/machine/uart.go
Outdated
| type UARTConfig struct { | ||
| BaudRate uint32 | ||
| TXPin uint8 | ||
| RXPin uint8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For I2C and SPI, the -Pin suffix is not used, they simply use MOSI, SDA, etc. It would be nice to keep the naming of these pins consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK I will make that change.
src/runtime/runtime_stm32.go
Outdated
|
|
||
| const ( | ||
| // Flash Access Control Register flag values. | ||
| FLASH_ACR_LATENCY_0 = 0x00000004 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This value looks suspicious. Shouldn't this be 0x00000001?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you are correct.
src/runtime/runtime_stm32.go
Outdated
| RCC_CFGR_PLLMUL_14 = 0x00300000 | ||
| RCC_CFGR_PLLMUL_15 = 0x00340000 | ||
| RCC_CFGR_PLLMUL_16 = 0x00380000 | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't seem to me like these constants belong in the runtime or machine package. It's very unfortunate that the .svd files provided by STMicro do not contain these bitfields, but I don't think putting them directly in the machine and runtime packages isn't the right thing to do either. Maybe they can be moved to src/device/stm32/stm32f103xx-bitfields.go, for example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those src/device directories are not currently under version control, which is why I did not put them there. Any other suggestions on how to better handle?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is src/device/nrf, src/device/arm, and src/device/avr. I think it's fine to add another directory.
Git doesn't track directories, only files. A file that is already tracked is not ignored by .gitignore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could use the -f flag to force the commit of such a bitfields file to the correct directory src/device/stm32/stm32f103xx-bitfields.go which seems like would accommodate this use case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I did it before simply by commenting out the lines in the .gitignore file before adding and uncommenting again afterwards. But maybe you can also try adding an exception to the .gitignore file.
…or future board imeplementation Signed-off-by: Ron Evans <ron@hybridgroup.com>
Signed-off-by: Ron Evans <ron@hybridgroup.com>
|
I think all the feedback has now been incorporated into this PR. Please let me know if anything else is needed. |
Signed-off-by: Ron Evans <ron@hybridgroup.com>
…32f103xx Signed-off-by: Ron Evans <ron@hybridgroup.com>
|
Merged in 47b667a. |
Support reusable workflows in the same repository
This PR implements UART0 for the STM32F103C8T6 aka Bluepill board.
You must have an FTDI adaptor/cable to use the UART on the Bluepill board. You can either use the default TX/RX pins
PA9/PA10or else use the alternate pinsPB6andPB7by specifying the UART configuration like this: