-
Notifications
You must be signed in to change notification settings - Fork 996
Teensy 3.6 #863
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
Teensy 3.6 #863
Conversation
|
I would love any help I can get on this. I am out of my depth when it comes to the low level stuff, such as the runtime files and linker scripts. @PaulStoffregen, would you be willing to advise and/or help? |
|
What I usually do is to try and find the most simple bare-metal C code that works, without any SDK. Just turning a LED on/off in an endless loop for example, without any delay even. You can often even ignore clock initialization. And then try and port it to Go, writing it directly in the |
|
For the linker script, you could start with this (copied from the microbit): Flash/RAM is much bigger than that, but it should work. This should also be a useful resource: https://www.seanet.com/~karllunt/bareteensy31.html |
|
I made a stripped down blink program using the Teensy 3 Arduino core. Besides |
|
I am trying to get blinky.go to compile, but I am running into odd errors. I'm building on macOS. Maybe XCode's clang is weird? package main
import (
"device/nxp"
"runtime/volatile"
"time"
"unsafe"
)
func main() {
mode := (*volatile.Register8)(unsafe.Pointer(uintptr(0x43FE1294)))
config := nxp.PORTC.PCR5
mode.Set(1)
config.SetBits(nxp.PORT_PCR5_SRE | nxp.PORT_PCR5_DSE | 1<<nxp.PORT_PCR0_MUX_Pos)
config.ClearBits(nxp.PORT_PCR5_ODE)
for {
nxp.GPIOC.PSOR.SetBits(1 << 5)
time.Sleep(time.Millisecond * 1000)
nxp.GPIOC.PCOR.SetBits(1 << 5)
time.Sleep(time.Millisecond * 1000)
}
}I got the address for |
|
Those Clang errors indicate that Clang does not get the correct My recommendation would be to just copy/modify that file, you can ignore float at least during the initial porting: {
"inherits": ["cortex-m"],
"llvm-target": "armv7em-none-eabi",
"build-tags": ["teensy36", "teensy", "mk66f18", "nxp"],
"cflags": [
"--target=armv7em-none-eabi",
"-Qunused-arguments"
],
"linkerscript": "targets/nxpmk66f18.ld",
"extra-files": [
"src/device/nxp/mk66f18.s"
],
"flash-command": "teensy_loader_cli -mmcu=mk66fx1m0 -v -w {hex}"
} |
That's an odd address. Maybe it is using bitbanding? Register addresses usually form a certain pattern. |
Ah, yes! There are bitband macros, but I had no idea what they were about. A partial expansion is #define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
#define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)))I updated |
|
I added bitband support (behind build tags) to package main
import (
"device/nxp"
"time"
)
func main() {
nxp.GPIOC.PDDR.Bit(5).Set(1)
nxp.PORTC.PCR5.SetBits(nxp.PORT_PCR5_SRE | nxp.PORT_PCR5_DSE | 1<<nxp.PORT_PCR0_MUX_Pos)
nxp.PORTC.PCR5.ClearBits(nxp.PORT_PCR5_ODE)
for {
nxp.GPIOC.PSOR.SetBits(1 << 5)
time.Sleep(time.Millisecond * 1000)
nxp.GPIOC.PCOR.SetBits(1 << 5)
time.Sleep(time.Millisecond * 1000)
}
} |
|
You should be able to simplify things by not using bitbanding. These regions are really just aliases for bits in registers. Instead, you can use SetBits and ClearBits which were designed for this purpose. To be honest, I think it would be best to leave it out initially. As far as I know, bitbanding is mainly an optimization. |
|
Have you gotten the LED to blink? You could perhaps try without bitbanding. These lines should be equivalent: nxp.GPIOC.PDDR.Bit(5).Set(1)
nxp.GPIOC.PDDR.SetBits(1 << 5)Also, you can try removing the |
|
Also, something that looks odd: nxp.GPIOC.PSOR.SetBits(1 << 5)
// ...
nxp.GPIOC.PCOR.SetBits(1 << 5)I think this should be: nxp.GPIOC.PSOR.Set(1 << 5)
// ...
nxp.GPIOC.PCOR.Set(1 << 5)If you haven't seen already, this is described in the 2000+ page Reference Manual for this chip, somewhere near the end in the GPIO peripheral. |
|
I have not tried to load anything onto the board (excluding C/C++ programs). I am currently working on translating the initialization code from the Teensy core libraries. Once I have that translated, I'll start trying to get it to work. I am using bit banding there because I blindly copied the contents of I'm not sure why I decided to use In the current version blinky, I am using |
|
I've been putting my test program in a gist: https://gist.github.com/firelizzard18/eaaa532f7ee18a7619b3b682490960ee |
|
I tried to create a PR to merge posborne/cmsis-svd into tinygo-org/cmsis-svd, but it seems that I can't do that |
|
I have translated all the initialization code, but blink does not work. Time to start debugging... |
|
The MK66FX1M0VMD18 requires a 16 byte flash config section at 0x400. |
|
Hi, Paul here, the guy behind Teensy. I can't get involved in Tiny Go, but I would like to quickly bring a couple issues about the 16 byte flash config to your attention. The FSEC byte controls powerful features, like security which prevents external access to memory, and an option to disable mass erase. If you activate both of these features, it will permanently disable reprogramming the flash. Normal programming over USB with Teensy Loader tries to prevent this from ever happening. It programs one of those bits which needs to be a 1 for that complete lock out to a 0. If you experiment with arbitrary values for FSEC, you'll see the byte that ends up in flash isn't always the same as what you defined. That is the lock-out safety feature at work, trying to prevent you from permanently bricking your Teensy! Teensy Loader does allow you to turn on the security feature. While this is recoverable, it does have some practical consequences. Normally when you press the button on Teensy, it enters programming mode, but nothing in flash actually changes until Teensy Loader sends new code. If you power cycle without programming, your code is still there and runs again. But security changes all that. Pressing the button causes complete flash erase. So be aware that a touch of that button becomes a code "self destruct" for flash memory. Not a big deal if you were going to upload new code, but something to keep in mind if the button is accidentally pressed. If you don't use the flash controller to do your own erasing and programming of the flash, using only Teensy Loader to write hex files, you should be safe while experimenting. But if you write your own code which erases those 16 bytes and writes them with new values, please remember you're running without a safety net. You can permanently brick your Teensy if the wrong bit pattern ends up in those flash config bytes! |
|
@PaulStoffregen that's very useful information, thank you for sharing! @firelizzard18 I wanted to say "use GDB with a debug probe to see what's wrong" and while that may be a good idea, I then stumbled on this post which shows that it's unfortunately not easy to set up on the Teensy 3.6. Still, a real debugger (available for under $20, and around $2 if you want to play with AliExpress-quality products) would probably make it much easier to see where the problem lies. I quickly looked at the linker script and it looks good to me. |
|
I have a SWD debugger and a soldering iron, so I'll see if I can hook it up without destroying something :P |
|
AFAICT, I fried my teensy, or at least the MKL02. I'll try debugging again once I have the equipment to completely remove the MKL02. |
|
Debugging the teensy is a no-go. My soldering skills are not up to that level of work. I might buy a FRDM-K66, but for now I'm going to have fun comparing disassembly listings. |
|
I have a bare minimum functioning (blinking) system, compiled with package main
import (
"device/arm"
"device/nxp"
_ "machine"
)
func main() {
nxp.GPIOC.PDDR.SetBits(1 << 5)
nxp.PORTC.PCR5.SetBits(nxp.PORT_PCR5_SRE | nxp.PORT_PCR5_DSE | 1<<nxp.PORT_PCR0_MUX_Pos)
nxp.PORTC.PCR5.ClearBits(nxp.PORT_PCR5_ODE)
for {
nxp.GPIOC.PSOR.Set(1 << 5)
for i := 0; i < 1<<23; i++ {
arm.Asm("nop")
}
nxp.GPIOC.PCOR.Set(1 << 5)
for i := 0; i < 1<<25; i++ {
arm.Asm("nop")
}
}
} |
|
Awesome! |
|
I can use |
|
|
Actually, looking more closely, I think you should avoid any changes all all to the existing USB code at this time. There are changes made in this PR that would be much better made as part of some other PR specific to refactoring USB code, and also I am pretty sure that you could be using some of the shared USB code instead of code that you have added. So that means just removing the last commit, it would appear. As @aykevl said we can take up getting the USB CDC working in a subsequent PR. I will wire up my setup for testing my Teensy 3.6 now. |
b37f0e2 to
3eee51d
Compare
|
@deadprogram I pushed some very minor modifications. Mostly I added
I didn't refactor the USB code so much as rearrange it so I could selectively exclude
I could and planned to use the descriptor structs and constructors more. But for the initial implementation, I wanted to keep everything as close to Paul's implementation as I could. I planned to modify
Would you like me to email you some Windows/USBPcap dumps? Wireshark understands *.pcap files. Since I don't know how to isolate the Teensy, this would include all of my USB traffic (because basically everything in my system is on a single root hub), so I am unwilling to post them publicly. |
|
FYI, all hell broke loose when I attempted to use UART0 directly from within the USB ISR. Hence why I write debug messages to a global variable. |
|
@firelizzard18 looks like you need to run |
|
I just tried this branch with the latest |
|
@deadprogram The build failure is fixed now. You might not be able to use |
|
Using this branch as of the last commit, I have blinky1 success! I did have to press the reset button when flashing, but then it worked. |
|
In further testing, I am able to run this branch against the TinyHCI and all of the current hardware passes. This PR certainly seems functional enough to merge to keep working on additional features. @aykevl or anyone else have any further comments here? |
|
@jaddr2line can you also please lookover this PR? Also anyone else who is interested. Thank you! |
|
Sorry @firelizzard18 but just one last merge conflict (hopefully!) to resolve, if you please. |
6a9e183 to
0e1caeb
Compare
|
@deadprogram Merge conflicts resolved |
- Fix UART & putChar - Timer-based sleep - Enable systick in abort - Buffered, interrupt-based UART TX - Use the new interrupt API and fix sleepTicks - Make pins behave more like other boards - Use the MCU's UART numbering - Allow interrupts to wake the scheduler (tinygo-org#1214)
|
At long last, time to merge this pull request. I know there are still things to be done for this board, but it will be a lot easier to work on those in smaller, more specific PRs. Thank you very much @firelizzard18 for all of your work on this contribution, and thanks everyone else who helped get it done. Now rebasing/merging. |
I want to use TinyGo for the Teensy 3.6, which is powered by the MK66FX1M0VMD18, a NXP Kinetis K66 processor. TinyGo does not currently support any NXP device.
src/device/nxp/mk66f18.gogen-device-svdto work with NXP SVDssrc/runtime/runtime_nxpmk66f18.go(and mayberuntime_nxp.go)src/machine/machine_nxpmk66f18.go(and maybemachine_nxp.go)src/machine/board_teensy36.gotargets/nxpmk66f18.ld,targets/nxpmk66f18.jsontargets/teensy36.json