igendel icon

EFM8BB1CLK UART TX demo

igendel | PRO | 07/10/20 12:11:06 PM UTC | 0 ⭐ | 2339 👁️ | Never ⏰ | []
C |

2.66 KB

|

None

|

0 👍

/

0 👎

// by Ido Gendel, 2020
// Share and enjoy!
 
#include <SI_EFM8BB1_Register_Enums.h>
 
char msg[] = "Hello World!        \n"; // Includes room for numbers
const uint8_t lastDigitPos = 19;
volatile char *cp;
 
// Do not read directly - use millis()
volatile uint32_t _millis = 0;
 
const uint8_t DEBOUNCE_MS = 10;
volatile uint8_t debounceMSLeft;
uint8_t oldButtonState = 1;
 
 
// This function is called immediately after reset, in SILABS_STARTUP.A51
void SiLabs_Startup (void) {
 
    // Disable watchdog
    WDTCN = 0xDE;
    WDTCN = 0xAD;
 
}
 
 
uint32_t millis(void) {
 
    uint32_t result;
 
    IE_EA = 0; // Disable interrupts
    result = _millis;
    IE_EA = 1; // Re-enable interrupts
    return result;
 
}
 
 
void setup(void) {
 
    P1MDOUT |= P1MDOUT_B4__PUSH_PULL; // Set built-in LED pin (P1.4) to push-pull output
    // Built-in button pin (P0.2) digital input by default
    // Weak pull-ups enabled by default.
    P0_B2 = 1;// Turn WPU on for button input
 
    // Default clock is internal 24.5MHz div 8
    // As a default, timers 0/1 uses system clock div 12 prescaler
    TMOD |= TMOD_T1M__MODE2; // Set Timer1 mode to 8-bit auto-reload
    TH1 = 243; // Set reload value to produce OVF @19.2KHz
    TCON_TR1 = 1; // Enable timer1
 
    TMOD |= TMOD_T0M__MODE1; // Set Timer0 mode to 16-bit
    TH0 = 0xFF; // Set Timer0 counter to overflow after 255 "ticks"
    TL0 = 0x01;
    TCON_TR0 = 1; // Enable timer0
 
    // Enable UART in crossbar; TX pin (P0.4) will become output automatically
    XBR0 |= XBR0_URT0E__ENABLED;
    // Enable crossbar
    XBR2 = 0x40;
 
    IE_ET0 = 1; // Enable timer0 interrupt
    IE_ES0 = 1; // Enable UART0 interrupt
    IE_EA = 1; // Enable interrupts globally
 
}
 
 
void populateSecondsText(void) {
 
    uint8_t i = lastDigitPos;
    uint32_t s = millis() / 1000;
 
    do {
        msg[i--] = s % 10 + 48;
        s = s / 10;
    } while (s > 0);
 
}
 
 
int main (void) {
 
    setup();
 
    for ( ; ; ) {
 
        if ((0 == debounceMSLeft) && (P0_B2 != oldButtonState)) {
 
            debounceMSLeft = DEBOUNCE_MS;
            oldButtonState = P0_B2;
            if (P0_B2) {
 
                P1_B4 = 0; // LED ON
                populateSecondsText();
                cp = &msg[1];
                SBUF0 = msg[0]; // Start UART transmission
 
            }
 
        }
 
    }
 
}
 
 
SI_INTERRUPT (TIMER0_OVF_ISR, TIMER0_IRQn) {
 
    // Interrupt flag is cleared automatically
    TH0 = 0xFF; // Reload counter value
    TL0 = 0x01;
    ++_millis;
    if (debounceMSLeft) {
        --debounceMSLeft;
    }
 
}
 
SI_INTERRUPT (UART0_ISR, UART0_IRQn) {
 
    // Transmit interrupt flag must be cleared in firmware:
    SCON0_TI = 0;
 
    // Anything left to transmit? (assuming null-terminated string)
    if (0 != *cp) {
        SBUF0 = *cp++;
    } else {
        P1_B4 = 1; // LED OFF
      }
 
}

Comments