2020-12-11 16:42:14 +01:00
|
|
|
/* 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 <iostream>
|
|
|
|
#include<time.h>
|
|
|
|
|
|
|
|
|
|
|
|
// 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 <stdint.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
/* 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
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|