/*---------------------------------------------------------------------------- * *---------------------------------------------------------------------------- * Name: slcd.c * Purpose: Microprocessors Laboratory *---------------------------------------------------------------------------- * *---------------------------------------------------------------------------*/ #include "slcd.h" //Declarations /*---------------------------------------------------------------------------- Function that initializes sLCD *----------------------------------------------------------------------------*/ void slcdInitialize(void){ SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | /* Enable Clock to Port B & C */ SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK | SIM_SCGC5_SLCD_MASK; /* Enable Clock to Port D & E and sLCD module*/ LCD->GCR |= LCD_GCR_PADSAFE_MASK; // Set PADSAFE during configuration LCD->GCR &= ~LCD_GCR_LCDEN_MASK; // Clear LCDEN during configuration //multiplexers configuration for ports to act as sLCD controller //TASK 2.3 - replace XXX with pin number, and YYY with proper alternative number PORTB->PCR[7] = PORT_PCR_MUX(0UL); PORTB->PCR[8] = PORT_PCR_MUX(0UL); PORTB->PCR[10] = PORT_PCR_MUX(0UL); PORTB->PCR[11] = PORT_PCR_MUX(0UL); PORTB->PCR[21] = PORT_PCR_MUX(0UL); PORTB->PCR[22] = PORT_PCR_MUX(0UL); PORTB->PCR[23] = PORT_PCR_MUX(0UL); PORTC->PCR[17] = PORT_PCR_MUX(0UL); PORTC->PCR[18] = PORT_PCR_MUX(0UL); PORTD->PCR[0] = PORT_PCR_MUX(0UL); PORTE->PCR[4] = PORT_PCR_MUX(0UL); PORTE->PCR[5] = PORT_PCR_MUX(0UL); //sLCD register configuration LCD->GCR = LCD_GCR_RVTRIM(0x00) | LCD_GCR_CPSEL_MASK | LCD_GCR_LADJ(0x03) | LCD_GCR_VSUPPLY_MASK | LCD_GCR_ALTDIV(0x00) | LCD_GCR_SOURCE_MASK | LCD_GCR_LCLK(0x01) | LCD_GCR_DUTY(0x03); //sLCD blinking configuration LCD->AR = LCD_AR_BRATE(0x03); //FDCR register configuration LCD->FDCR = 0x00000000; //activation of 12 pins to control sLCD (2 registers, 32 bits each) LCD->PEN[0] = LCD_PEN_PEN(1u<<7) | // LCD_P7 LCD_PEN_PEN(1u<<8) | // LCD_P8 LCD_PEN_PEN(1u<<10) | // LCD_P10 LCD_PEN_PEN(1u<<11) | // LCD_P11 LCD_PEN_PEN(1u<<17) | // LCD_P17 LCD_PEN_PEN(1u<<18) | // LCD_P18 LCD_PEN_PEN(1u<<19); // LCD_P19 LCD->PEN[1] = LCD_PEN_PEN(1u<<5) | // LCD_P37 LCD_PEN_PEN(1u<<6) | // LCD_P38 LCD_PEN_PEN(1u<<8) | // LCD_P40 LCD_PEN_PEN(1u<<20) | // LCD_P52 LCD_PEN_PEN(1u<<21); // LCD_P53 //configuration of 4 back plane pins (2 registers, 32 bits each) LCD->BPEN[0] = LCD_BPEN_BPEN(1u<<18) | //LCD_P18 LCD_BPEN_BPEN(1u<<19); //LCD_P19 LCD->BPEN[1] = LCD_BPEN_BPEN(1u<<8) | //LCD_P40 LCD_BPEN_BPEN(1u<<20); //LCD_P52 // waveform registers configuration – 4 active (because of 4 back planes) // (44.3.7 in KL46 Reference Manual) LCD->WF[4] = LCD_WF_WF16(0x00) | LCD_WF_WF17(0x00) | LCD_WF_WF18(0x88) | // COM3 (10001000) LCD_WF_WF19(0x44); // COM2 (01000100) LCD->WF[10] = LCD_WF_WF40(0x11) | // COM0 (00010001) LCD_WF_WF41(0x00) | LCD_WF_WF42(0x00) | LCD_WF_WF43(0x00); LCD->WF[13] = LCD_WF_WF52(0x22) | // COM1 (00100010) LCD_WF_WF53(0x00) | LCD_WF_WF54(0x00) | LCD_WF_WF55(0x00); LCD->GCR &= ~LCD_GCR_PADSAFE_MASK; // Clear PADSAFE at the end of configuration LCD->GCR |= LCD_GCR_LCDEN_MASK; // Set LCDEN at the end of configuration } /*---------------------------------------------------------------------------- Function that outputs on sLCD (number) error message for debug purpose *----------------------------------------------------------------------------*/ void slcdErr(uint8_t number){ LCD->WF8B[LCD_Front_Pin[0]] = (LCD_S_G | LCD_S_E | LCD_S_D | LCD_S_F); //1st digit LCD->WF8B[LCD_Front_Pin[1]] = (LCD_S_A); LCD->WF8B[LCD_Front_Pin[2]] = (LCD_S_E | LCD_S_G); //2nd digit LCD->WF8B[LCD_Front_Pin[3]] = (LCD_C); LCD->WF8B[LCD_Front_Pin[4]] = (LCD_S_E | LCD_S_G); //3rd digit LCD->WF8B[LCD_Front_Pin[5]] = (LCD_C); switch(number){ //4 digit depends on provided number case 0x00: LCD->WF8B[LCD_Front_Pin[6]] = (LCD_S_D | LCD_S_E | LCD_S_F); /* To display '0' we must active segments: d, e & f on first front plane */ LCD->WF8B[LCD_Front_Pin[7]] = (LCD_S_A | LCD_S_B | LCD_S_C); /* To display '0' we must active segments: a, b & c on second front plane */ break; case 0x01: LCD->WF8B[LCD_Front_Pin[6]] = (LCD_C); //TASK 2.5 - replace ZZZ with segment definition, do czyszczenia LCD->WF8B[LCD_Front_Pin[7]] = (LCD_S_B | LCD_S_C); //TASK 2.5 - replace ZZZ with segment definition break; case 0x02: LCD->WF8B[LCD_Front_Pin[6]] = (LCD_S_G | LCD_S_E | LCD_S_D ); //TASK 2.5 - replace ZZZ with segment definition LCD->WF8B[LCD_Front_Pin[7]] = (LCD_S_A | LCD_S_B); //TASK 2.5 - replace ZZZ with segment definition break; case 0x03: LCD->WF8B[LCD_Front_Pin[6]] = (LCD_S_G | LCD_S_D); //TASK 2.5 - replace ZZZ with segment definition LCD->WF8B[LCD_Front_Pin[7]] = (LCD_S_A | LCD_S_B | LCD_S_C); //TASK 2.5 - replace ZZZ with segment definition break; case 0x04: LCD->WF8B[LCD_Front_Pin[6]] = (LCD_S_G | LCD_S_F); LCD->WF8B[LCD_Front_Pin[7]] = (LCD_S_B | LCD_S_C); break; default: //as default display 'r' LCD->WF8B[LCD_Front_Pin[6]] = (LCD_S_E | LCD_S_G); LCD->WF8B[LCD_Front_Pin[7]] = (LCD_C); break; } } /*---------------------------------------------------------------------------- Writing on sLCD (value) on specified position (digit) * * FP0 - Front Plane 0 * f |_g * e |_ * d * * FP1 - Front Plane 1 * a_ * | b * c |. * dot *----------------------------------------------------------------------------*/ void slcdSet(uint8_t value, uint8_t digit){ switch(value){ case 0x00: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_S_D | LCD_S_E | LCD_S_F); /* To display '0' we must active segments: d, e & f on first front plane */ LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_A | LCD_S_B | LCD_S_C); /* To display '0' we must active segments: a, b & c on second front plane */ break; case 0x01: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_C); //TASK 2.5 - replace ZZZ with segment definition LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_B | LCD_S_C); //TASK 2.5 - replace ZZZ with segment definition break; case 0x02: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_S_G | LCD_S_E | LCD_S_D ); //TASK 2.5 - replace ZZZ with segment definition LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_A | LCD_S_B); //TASK 2.5 - replace ZZZ with segment definition break; case 0x03: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_S_G | LCD_S_D); //TASK 2.5 - replace ZZZ with segment definition LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_A | LCD_S_B | LCD_S_C); //TASK 2.5 - replace ZZZ with segment definition break; case 0x04: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_S_G | LCD_S_F); LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_B | LCD_S_C); break; case 0x05: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_S_G | LCD_S_F | LCD_S_D); LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_A | LCD_S_C); break; case 0x06: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_S_G | LCD_S_E | LCD_S_D | LCD_S_F); LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_A | LCD_S_C); break; case 0x07: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_C); LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_A | LCD_S_B | LCD_S_C); break; case 0x08: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_S_G | LCD_S_E | LCD_S_D | LCD_S_F); LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_A | LCD_S_B | LCD_S_C); break; case 0x09: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_S_F | LCD_S_G | LCD_S_D); LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_A | LCD_S_B | LCD_S_C); break; case 0x0A: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_S_F | LCD_S_E | LCD_S_G); LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_A | LCD_S_B | LCD_S_C); break; case 0x0B: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_S_C); LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_G | LCD_S_E | LCD_S_D | LCD_S_F); break; case 0x0C: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_S_F | LCD_S_E | LCD_S_D); LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_A); break; case 0x0D: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_S_G | LCD_S_E | LCD_S_D); LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_B | LCD_S_C); break; case 0x0E: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_S_G | LCD_S_E | LCD_S_D | LCD_S_F); LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_A); break; case 0x0F: LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_S_F | LCD_S_E | LCD_S_G); LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_S_A); break; default: //as default display 'r' LCD->WF8B[LCD_Front_Pin[((2*digit)-2)]] = (LCD_S_E | LCD_S_G); LCD->WF8B[LCD_Front_Pin[((2*digit)-1)]] = (LCD_C); break; } if(digit>4){ slcdErr(1); } } /*---------------------------------------------------------------------------- Function for conversion purpose, displaying (value) in specified (format) *----------------------------------------------------------------------------*/ void slcdDisplay(uint16_t value ,uint16_t format){ //uint16_t tab[4] = {1, 2, 3, 4}; //int i = 0; uint16_t tVariable = 0; /* TASK 2.7: Write value to the table in specified format */ uint16_t x[4]; x[3] = value % format; tVariable = value - x[3]; //full number of system x[2] = tVariable / format % format; x[1] = tVariable / (format*format) %format; x[0] = tVariable / (format*format*format) % format; slcdSet(x[0], 1); slcdSet(x[1], 2); slcdSet(x[2], 3); slcdSet(x[3], 4); /*for(i=0; i < 4; i++){ slcdClear(); slcdSet(x[i], i+1); delay_mc(300); slcdClear(); }*/ } /*---------------------------------------------------------------------------- Clear sLCD *----------------------------------------------------------------------------*/ void slcdClear(void){ uint8_t i = 0; for(i=0; i < 8; i++){ LCD->WF8B[LCD_Front_Pin[i]] = LCD_C; } } /*---------------------------------------------------------------------------- Function for demo purpose *----------------------------------------------------------------------------*/ void slcdDemo(void){ uint8_t i; for(i=0; i < 0x10; i++){ slcdClear(); slcdSet(i, i%4 + 1); delay_mc(300); slcdClear(); } }