-
Notifications
You must be signed in to change notification settings - Fork 0
Implement LED PWM brightness control #1
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| #ifndef __PRU_AM1808_H__ | ||
| #define __PRU_AM1808_H__ | ||
|
|
||
| // PRU0/1 Local INTC | ||
| #pragma ctable_entry 0 0x00004000 | ||
| // Timer64P0 | ||
| #pragma ctable_entry 1 0x01C20000 | ||
| // I2C0 | ||
| #pragma ctable_entry 2 0x01C22000 | ||
| // PRU0/1 Local Data (self) | ||
| #pragma ctable_entry 3 0x00000000 | ||
| // PRU1/0 Local Data (other) | ||
| #pragma ctable_entry 4 0x00002000 | ||
| // MMC/SD | ||
| #pragma ctable_entry 5 0x01C40000 | ||
| // SPI0 | ||
| #pragma ctable_entry 6 0x01C41000 | ||
| // UART0 | ||
| #pragma ctable_entry 7 0x01C42000 | ||
| // McASP0 DMA | ||
| #pragma ctable_entry 8 0x01D02000 | ||
| // Reserved | ||
| #pragma ctable_entry 9 0x01D06000 | ||
| // Reserved | ||
| #pragma ctable_entry 10 0x01D0A000 | ||
| // UART1 | ||
| #pragma ctable_entry 11 0x01D0C000 | ||
| // UART2 | ||
| #pragma ctable_entry 12 0x01D0D000 | ||
| // USB0 | ||
| #pragma ctable_entry 13 0x01E00000 | ||
| // USB1 | ||
| #pragma ctable_entry 14 0x01E25000 | ||
| // UHPI Config | ||
| #pragma ctable_entry 15 0x01E10000 | ||
| // Reserved | ||
| #pragma ctable_entry 16 0x01E12000 | ||
| // I2C1 | ||
| #pragma ctable_entry 17 0x01E28000 | ||
| // EPWM0 | ||
| #pragma ctable_entry 18 0x01F00000 | ||
| // EPWM1 | ||
| #pragma ctable_entry 19 0x01F02000 | ||
| // Reserved | ||
| #pragma ctable_entry 20 0x01F04000 | ||
| // ECAP0 | ||
| #pragma ctable_entry 21 0x01F06000 | ||
| // ECAP1 | ||
| #pragma ctable_entry 22 0x01F07000 | ||
| // ECAP2 | ||
| #pragma ctable_entry 23 0x01F08000 | ||
|
|
||
| /* 24 and 25 are variable */ | ||
| // 24 = PRU0/1 Local Data 0x00000n00 | ||
| // 25 = McASP0 Control 0x01D00n00 | ||
|
|
||
| // Reserved | ||
| #pragma ctable_entry 26 0x01D04000 | ||
| // Reserved | ||
| #pragma ctable_entry 27 0x01D08000 | ||
|
|
||
| /* 28-31 are variable */ | ||
| // 28 = DSP Megamodule RAM/ROM 0x11nnnn00 | ||
| // 29 = EMIFA SDRAM 0x40nnnn00 | ||
| // 30 = Shared RAM 0x80nnnn00 | ||
| // 31 = mDDR/DDR2 Data 0xC0nnnn00 | ||
|
|
||
| // Timer0 peripheral (only what we need) | ||
| static volatile uint32_t * const TIMER0_TIM34 = (volatile uint32_t *)0x01C20014; | ||
|
|
||
| #endif | ||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -1,3 +1,52 @@ | ||||||||
| #include <stdint.h> | ||||||||
|
|
||||||||
| #include "am1808.h" | ||||||||
|
|
||||||||
| // Shared RAM (control input) | ||||||||
| typedef struct shared_ram { | ||||||||
| // Declare this as a u32 to force more-efficient codegen | ||||||||
| uint32_t pwms; | ||||||||
| } shared_ram; | ||||||||
| // XXX: The real address in use here is 0x80010000 | ||||||||
| // There appears to be a compiler bug where ctable entries with the MSB set | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have a link for the bug we could add here?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm working on filing a bug right this moment, but unfortunately GCC's bug tracker seems to want manual approval for new account creation. I have produced a minimal testcase though: #pragma ctable_entry 30 0x00beef00
void good() {
*(volatile unsigned int *)0x00beef00 = 0xdead;
}
#pragma ctable_entry 31 0x80beef00
void bad() {
*(volatile unsigned int *)0x80beef00 = 0xf00d;
}
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just filed https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121124 to track this issue. |
||||||||
| // do not get optimized correctly. We lie to the PRU compiler here, but the | ||||||||
| // hardware indeed contains the correct address we *actually* want. | ||||||||
| static volatile shared_ram * const SHARED = (volatile shared_ram *)0x7f010000; | ||||||||
| #pragma ctable_entry 30 0x7f010000 | ||||||||
|
|
||||||||
| // LED definitions | ||||||||
| // LEDx corresponds to DIODEx in the EV3 schematics | ||||||||
| // LEDx defined as n ==> pin is PRU1_R30[n] | ||||||||
| #define LED0 12 | ||||||||
| #define LED1 10 | ||||||||
| #define LED2 13 | ||||||||
| #define LED3 11 | ||||||||
|
|
||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
| static inline void update_pwm(uint8_t val, uint8_t time_now, uint32_t gpio_bit) { | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
| // We want to force generation of the optimized set/clr opcodes | ||||||||
| if (time_now < val) { | ||||||||
| asm volatile("set r30, r30, %0"::"I"(gpio_bit)); | ||||||||
| } else { | ||||||||
| asm volatile("clr r30, r30, %0"::"I"(gpio_bit)); | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| void main() { | ||||||||
| __halt(); | ||||||||
| uint32_t pwms = 0; | ||||||||
| while (1) { | ||||||||
| // 24 MHz / 256 ==> 93.75 kHz tick rate for this counter | ||||||||
| uint8_t time_now = (*TIMER0_TIM34) >> 8; | ||||||||
|
|
||||||||
| if (time_now == 0) { | ||||||||
| // 24 MHz / 256 / 256 ~= 366 Hz update rate | ||||||||
| pwms = SHARED->pwms; | ||||||||
ArcaneNibble marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
| } | ||||||||
|
|
||||||||
| update_pwm(pwms >> 0, time_now, LED0); | ||||||||
| update_pwm(pwms >> 8, time_now, LED1); | ||||||||
| // Intentional swap of 2 and 3 | ||||||||
| // This puts the pins into the order R, G, R, G | ||||||||
| update_pwm(pwms >> 16, time_now, LED3); | ||||||||
| update_pwm(pwms >> 24, time_now, LED2); | ||||||||
| } | ||||||||
| } | ||||||||
Uh oh!
There was an error while loading. Please reload this page.