/* Simple simulator for Kinetis KL25Z MCU * Main implementation file. * Ad this file to your project to be build with your sources. * Requires C++11 support. */ #include "simul_kl25z.h" #include #include // Delay with time in milliseconds void delay(unsigned int mseconds) { clock_t goal = mseconds + clock(); while (goal > clock() ) ; } // simple delay with some default value void delay(void) { delay(500); } // clear screen void clear(){ #if defined(__linux__) || defined(__unix__) || defined(__APPLE__) system("clear"); #endif #if defined(_WIN32) || defined(_WIN64) system("cls"); #endif } char screenBuffer[1024]; void WriteLEDsToScreen(); // in drv_gpio void WriteLCDToScreen(); // in drv_lcd void WriteLEDsToBuffer(char* buffer); // in drv_gpio void WriteLCDToBuffer(char* buffer); // in drv_lcd void UpdateScreen() { // Verze s vystupem pres buffer //screenBuffer[0] = '\0'; //WriteLEDsToBuffer(screenBuffer); //WriteLCDToBuffer(screenBuffer); //clear(); //printf(screenBuffer); // Verze s primym vystupem na obrazovku // pozor omezeni refresh pomoci clock by nekdy neprekreslilo posledni stav, // kdyby se znovu nevovalo updateScreen... //static clock_t lastUpdate = clock(); //if ( clock() - lastUpdate > 40 ) { // lastUpdate = clock(); clear(); printf("KL25Z Simulation, version %d.%d\n\n", VERSION_MAJOR, VERSION_MINOR); WriteLEDsToScreen(); WriteLCDToScreen(); //} else { // printf("skipping update\n"); //} } ////////////////////////////////////////////// static SIM_Peripheral sim_peripheral_object; SIM_Peripheral* SIM = &sim_peripheral_object; // Port C module (needed for ADC input on port C) static PORT_Peripheral portc_peripheral_object; PORT_Peripheral* PORTC = &portc_peripheral_object; ////////////////////////////////////////////////// // GPIO driver code #include #include #include #include /* Internal functions */ //static void f_GPIO_set_pin_mode(PORT_Type* port, GPIO_Type* gpio, uint8_t pin, FRDM_kit_pinmode mode ); /* Example of internal constants*/ /*const char UTB_UART_CR = (const char)0x0D;*/ static bool gInitialized; static FRDM_kit_pinmode gPinModes[LAST_PIN]; static uint8_t gPinOutputValues[LAST_PIN]; static const char* gLedNames[] = {"LD1", "LD2", "LD3", "RED", "GREEN", "BLUE" }; void WriteLEDsToScreen(); /* Initialize the gpio driver for LEDs and push buttons. */ void GPIO_Initialize(void) { gInitialized = true; } /* Configure given pin to behave as input or output. */ void pinMode(FRDM_kit_pin pin, FRDM_kit_pinmode mode ) { if ( !gInitialized ) { printf("BSOD - Default ISR :) \nGPIO driver not initialized!\n"); while (1) ; } switch (pin) { /* All LEDs are on port B */ case LD1: case LD2: case LD3: case LED_RED: case LED_GREEN: case LED_BLUE: case SW1: case SW2: case SW3: case SW4: gPinModes[(int)pin] = mode; break; default: printf("Warning: Invalid pin %d in pinMode.\n", pin); //while (1) ; /* Error: invalid pin! */ } } /* Set value for given pin. The pin must be configured as output with pinMode first! */ void pinWrite(FRDM_kit_pin pin, uint8_t value ) { if ( !gInitialized ) { printf("BSOD - Default ISR :) \nGPIO driver not initialized!\n"); while (1) ; } switch(pin) { /* All LEDs are on port B */ case LD1: case LD2: case LD3: case LED_RED: case LED_GREEN: case LED_BLUE: case SW1: case SW2: case SW3: case SW4: if ( gPinModes[(int)pin] == OUTPUT ) { // zapis na konzolu gPinOutputValues[(int)pin] = value; UpdateScreen(); //WriteLEDsToScreen(); } else { // nedelej nic printf("Warning: Pin %d is not an output.\n", pin); } break; default: printf("Warning: Invalid pin %d in pinWrite.\n", pin); //while(1) ; /* Error: invalid pin! */ } } /* Read value on given pin. The pin must be configured as input with pinMode first! */ uint8_t pinRead(FRDM_kit_pin pin) { if ( !gInitialized ) { printf("BSOD - Default ISR :) \nGPIO driver not initialized!\n"); while (1) ; } /* uint8_t retVal = LOW; switch(pin) { case LD1: case LD2: case LD3: case LED_RED: case LED_GREEN: if ((PTB->PDIR & (1 << (uint8_t)pin)) == 0) retVal = LOW; else retVal = HIGH; break; case SW1: case SW2: case SW3: case SW4: if ((PTA->PDIR & (1 << (uint8_t)pin)) == 0) retVal = LOW; else retVal = HIGH; break; default: while(1) ; } */ uint8_t retVal = LOW; switch(pin) { /* All LEDs are on port B */ case LD1: case LD2: case LD3: case LED_RED: case LED_GREEN: case LED_BLUE: case SW1: case SW2: case SW3: case SW4: if ( gPinModes[(int)pin] == INPUT || gPinModes[(int)pin] == INPUT_PULLUP ) { // todo: cteni vstupu z konzole } else { // nedelej nic printf("Warning: Pin %d is not an input.\n", pin); } break; default: while(1) ; /* Error: invalid pin! */ } return retVal; } // Helpers to print LED state to console #define GET_LED_SYMBOL(a) ((a == 0) ? 'X' : '-') #define PRINT_LED_FROM_MODE(mode, value) ((mode == OUTPUT) ? GET_LED_SYMBOL(value) : '-') void WriteLEDsToBuffer(char* buffer) { char buff[512]; sprintf(buff, "%5c%5c%5c\t\t%3c%3c%3c\n", PRINT_LED_FROM_MODE(gPinModes[0], gPinOutputValues[0]), PRINT_LED_FROM_MODE(gPinModes[1], gPinOutputValues[1]), PRINT_LED_FROM_MODE(gPinModes[2], gPinOutputValues[2]), PRINT_LED_FROM_MODE(gPinModes[3], gPinOutputValues[3]), PRINT_LED_FROM_MODE(gPinModes[4], gPinOutputValues[4]), PRINT_LED_FROM_MODE(gPinModes[5], gPinOutputValues[5]) ); strcat(buffer, buff); sprintf(buff, "%5s%5s%5s\t\t%s/%s/%s\n", gLedNames[0], gLedNames[1], gLedNames[2], gLedNames[3], gLedNames[4], gLedNames[5]); strcat(buffer, buff); } void WriteLEDsToScreen() { printf("%5c%5c%5c\t\t%3c%3c%3c\n", PRINT_LED_FROM_MODE(gPinModes[0], gPinOutputValues[0]), PRINT_LED_FROM_MODE(gPinModes[1], gPinOutputValues[1]), PRINT_LED_FROM_MODE(gPinModes[2], gPinOutputValues[2]), PRINT_LED_FROM_MODE(gPinModes[3], gPinOutputValues[3]), PRINT_LED_FROM_MODE(gPinModes[4], gPinOutputValues[4]), PRINT_LED_FROM_MODE(gPinModes[5], gPinOutputValues[5]) ); printf("%5s%5s%5s\t\t%s/%s/%s\n", gLedNames[0], gLedNames[1], gLedNames[2], gLedNames[3], gLedNames[4], gLedNames[5]); } // end GPIO driver code ////////////////////////////////////////////////// ////////////////////////////////////////////////// // ADC code // Simulated ADC values static uint16_t adc_values[] = { 10, 30, 60, 100, 110, 120, 130, 140, 150, 170, 200, 230, 255, 230, 200, 170, 150, 130, 100, 60, 30, 0, 0 }; static int MAX_ADC_VALUES = sizeof(adc_values)/sizeof(uint16_t); // Define the ADC0 module for use in user program static ADC_Peripheral adc_module_object; ADC_Peripheral* ADC0 = &adc_module_object; void AdcValueWrite(unsigned int data) { (void)data; // just to remove unused param warning //std::cout << "Volan handler " << data << '\n'; ADC0->UpdateData(); } // handler for write to CFG1[0] only to indicate we have valid settings void AdcStartConversion(unsigned int data) { //(void)data; // just to remove unused param warning //std::cout << "Start conversion " << data << '\n'; // For our pin - channel 11 check the pin config, for other channels just // skip test and simulated that conversion completed. This is needed for // calibration etc. int channel = (data & ADC_SC1_ADCH_MASK) >> ADC_SC1_ADCH_SHIFT; if ( channel == 11 ) { if ( ADC0->IsPinConfigValid() ) ADC0->mConversionStarted = true; } else { // conversion must be started for any other channel, also for calibration ADC0->mConversionStarted = true; } ADC0->UpdateData(); } void ADC_Peripheral::UpdateData() { // test if clock is enabled if ( (SIM->SCGC6 & SIM_SCGC6_ADC0_MASK) == 0 ) { printf("BSOD - Default ISR :) \nADC - clock not enabled!\n"); while (1) ; } if ( mConversionStarted ) { // get next value for ADC if channel is 11 if ( (SC1[0] & 0x1F) == ADC_SC1_ADCH(11) ) { // rozliseni int mode = (CFG1 & ADC_CFG1_MODE_MASK) >> ADC_CFG1_MODE_SHIFT; int shift = 0; switch ( mode) { case 0: // 8 bit shift = 0; PRINT_DGMSG("ADC resolution is 8 bit."); break; case 1: // 12 bit shift = 4; PRINT_DGMSG("ADC resolution is 12 bit."); break; case 2: // 10 bit shift = 2; PRINT_DGMSG("ADC resolution is 10 bit."); break; case 3: // 16 bit shift = 8; PRINT_DGMSG("ADC resolution is 16 bit."); break; } R[0].data = adc_values[mCurrentDataIndex++] << shift; if ( mCurrentDataIndex >= MAX_ADC_VALUES ) mCurrentDataIndex = 0; } SC1[0].data |= ADC_SC1_COCO_MASK; // set conversion complete flag mConversionStarted = false; } } // end ADC driver code ////////////////////////////////////////////////// //////////////////////////////////////////////////////////// // LCD driver code static bool gLcdInitialized; static char gDispData[4][21]; static int gRow, gColumn; void WriteLCDToScreen() { //clear(); printf("\n\nLCD-----------------\n"); //printf("123456789ABCDEFGHIJK\n"); for ( int i=0; i<4; i++ ) printf("%s\n", gDispData[i]); printf("---------------------\n"); } void WriteLCDToBuffer(char* buffer) { //clear(); char buff[512]; sprintf(buff, "\n\nLCD-----------------\n"); strcat(buffer, buff); //printf("123456789ABCDEFGHIJK\n"); for ( int i=0; i<4; i++ ) { sprintf(buff, "%s\n", gDispData[i]); strcat(buffer, buff); } sprintf(buff, "---------------------\n"); strcat(buffer, buff); } /* initialize display */ void LCD_initialize(void) { gLcdInitialized = true; gRow = 0; // 1 - 4 gColumn = 0; // 1 - 20 } void LCD_set_cursor(uint8_t line, uint8_t column) { //printf("Warning: LCD_set_cursor not implemented.\n"); if ( line > 0 && line < 5) gRow = line - 1; if ( column > 0 && column < 21 ) gColumn = column - 1; } void LCD_putch(char c) { if ( !gLcdInitialized ) { printf("BSOD - Default ISR :) \nLCD driver not initialized!\n"); while (1) ; } if ( gColumn > 19 ) { printf("Warning: LCD writing beyond last column!\n"); return; } if ( gRow > 3 ) { printf("Warning: LCD writing below last line!\n"); return; } gDispData[gRow][gColumn] = c; gColumn++; if ( gColumn > 19 ) gColumn = 0; UpdateScreen(); } void LCD_puts(const char* str) { if ( !gLcdInitialized ) { printf("BSOD - Default ISR :) \nLCD driver not initialized!\n"); while (1) ; } char* p = gDispData[gRow]; int len = 20 - gColumn; if ( len > 0) { strncpy(p + gColumn, str, len); gDispData[gRow][gColumn+len] = '\0'; gColumn += strlen(str); } else { printf("Warning: LCD writing beyond last column!\n"); return; } UpdateScreen(); } void LCD_clear(void) { if ( !gLcdInitialized ) { printf("BSOD - Default ISR :) \nLCD driver not initialized!\n"); while (1) ; } gRow = 0; // 1 - 4 gColumn = 0; for ( int i = 0; i<4; i++ ) { for ( int j = 0; j<20; j++) { gDispData[i][j] = ' '; } } UpdateScreen(); } void LCD_backlight_on(void) { printf("Warning: LCD_backlight_on not implemented.\n"); } void LCD_backlight_off(void) { printf("Warning: LCD_backlight_off not implemented.\n"); } // end LCD driver code //////////////////////////////////////////////////////////////////