#include "LPC17xx.h" #include "GLCD.h" #include //------- ITM Stimulus Port definitions for printf ------------------- // #define ITM_Port8(n) (*((volatile unsigned char *)(0xE0000000+4*n))) #define ITM_Port16(n) (*((volatile unsigned short*)(0xE0000000+4*n))) #define ITM_Port32(n) (*((volatile unsigned long *)(0xE0000000+4*n))) #define DEMCR (*((volatile unsigned long *)(0xE000EDFC))) #define TRCENA 0x01000000 struct __FILE { int handle; }; FILE __stdout; FILE __stdin; int fputc(int ch, FILE *f) { if (DEMCR & TRCENA) { while (ITM_Port32(0) == 0); ITM_Port8(0) = ch; } return(ch); } //------------------------------------------------------------------- // #define __USE_LCD 0 // Uncomment to use the LCD #define __FI 1 // Font index 16x24 // Bit Band Macros used to calculate the alias address at run time #define ADDRESS(x) (*((volatile unsigned long *)(x))) #define BitBand(x, y) ADDRESS(((unsigned long)(x) & 0xF0000000) | 0x02000000 |(((unsigned long)(x) & 0x000FFFFF) << 5) | ((y) << 2)) #ifdef __USE_LCD static inline void method2lcd(unsigned char* msg) { GLCD_DisplayString(6, 8, __FI, msg); } #endif // Simple register masking static void method_mask(){ LPC_GPIO1->FIOPIN ^= (1 << 28); LPC_GPIO2->FIOPIN ^= (1 << 2); } // Define pointer with bitband method static void method_function(){ volatile unsigned long* bit1 = &BitBand(&LPC_GPIO1->FIOPIN, 29); volatile unsigned long* bit2 = &BitBand(&LPC_GPIO2->FIOPIN, 3); static _Bool state = 1; *bit1 = *bit2 = state; state = !state; } // Raw bitbanding static void method_bitbanding() { const size_t addr1 = 0x22000000 + (0x2009C034 * 32UL) + (31 * 4); const size_t addr2 = 0x22000000 + (0x2009C054 * 32UL) + (4 * 4); static _Bool state = 1; ADDRESS(addr1) = ADDRESS(addr2) = state; state = !state; } void SysTick_Handler(void) { static size_t tick = 0; static size_t state = 0; if (tick++ < 500) { return; } tick = 0; // Uses MOVS instruction to implement jump table if (state == 0) { method_mask(); state++; } else if (state == 1) { method_function(); state++; } else if (state == 2) { method_bitbanding(); state = 0; } #ifdef __USE_LCD if (state == 1) { method2lcd("MASK "); } else if (state == 2) { method2lcd("FUNCTION"); } else if (state == 0) { method2lcd("BITBAND "); } #endif } int main(void){ LPC_SC->PCONP |= (1 << 15); /* enable power to GPIO & IOCON */ LPC_GPIO1->FIODIR |= 0xB0000000; /* LEDs on PORT1 are output */ LPC_GPIO2->FIODIR |= 0x0000007C; /* LEDs on PORT2 are output */ // Configure SysTick with interrupt and internal clock source ADDRESS(0xE000E010) = (1 << 0) | (1 << 1) | (1 << 2); // Run handler every 1ms ADDRESS(0xE000E014) = 99999; #ifdef __USE_LCD GLCD_Init(); /* Initialize graphical LCD (if enabled */ GLCD_Clear(White); /* Clear graphical LCD display */ GLCD_SetBackColor(Blue); GLCD_SetTextColor(Yellow); GLCD_DisplayString(0, 0, __FI, " COE718 Lab 2 "); GLCD_SetTextColor(White); GLCD_DisplayString(1, 0, __FI, " bitband.c "); GLCD_DisplayString(2, 0, __FI, " Watch the LEDs! "); GLCD_SetBackColor(White); GLCD_SetTextColor(Blue); GLCD_DisplayString(6, 0, __FI, "Method:"); #endif // Let SysTick callback run in background while (1) {} }