Bootloader dla zestawu FREEboard – wprowadzenie
Prawidłowe funkcjonowanie interfejsów komunikacyjnych, takich jak np. I2C, SPI oraz UART, uzależnione jest od konfiguracji zarówno odpowiednich modułów jak również powiązanych z nimi wyprowadzeń. W większości mikrokontrolerów z rodziny KINETIS konfiguracja modułów peryferyjnych jest podobna, a różnica występuje w zakresie wyprowadzeń, gdzie do poszczególnych linii przypisana jest lista możliwych funkcji alternatywnych. Stąd też w pliku hardware_init_x.c zdefiniowane są wymagane funkcje konfigurujące, m.in. x_pinmux_config(), init_hardware() oraz deinit_hardware() (przykład dla układów z serii KL25Z):
/* This function is called for configurating pinmux for uart module
* This function only support switching default or gpio or fixed-ALTx mode on fixed pins
* (Although there are many ALTx-pinmux configuration choices on various pins for the same
* peripheral module) */
void uart_pinmux_config(unsigned int instance, pinmux_type_t pinmux){
switch(instance)
{
case 0:
switch(pinmux)
{
case kPinmuxType_Default:
BW_PORT_PCRn_MUX(HW_PORTA, UART0_RX_GPIO_PIN_NUM, 0);
BW_PORT_PCRn_MUX(HW_PORTA, UART0_TX_GPIO_PIN_NUM, 0);
break;
case kPinmuxType_GPIO:
// Set UART0_RX pin in GPIO mode
BW_PORT_PCRn_MUX(HW_PORTA, UART0_RX_GPIO_PIN_NUM, UART0_RX_GPIO_ALT_MODE);
// Set UART0_RX pin as an input
HW_GPIO_PDDR_CLR(HW_GPIOA, 1 << UART0_RX_GPIO_PIN_NUM);
break;
case kPinmuxType_Peripheral:
// Set UART0_RX pin to UART0_RX functionality
BW_PORT_PCRn_MUX(HW_PORTA, UART0_RX_GPIO_PIN_NUM, UART0_RX_ALT_MODE);
// Set UART0_TX pin to UART0_TX functionality
BW_PORT_PCRn_MUX(HW_PORTA, UART0_TX_GPIO_PIN_NUM, UART0_TX_ALT_MODE);
break;
default:
break;
}
break;
case 1:
break;
case 2:
break;
default:
break;
}
}
/* This function is called for configurating pinmux for i2c module
* This function only support switching default or gpio or fixed-ALTx mode on fixed pins
* (Although there are many ALTx-pinmux configuration choices on various pins for the same
* peripheral module) */
void i2c_pinmux_config(unsigned int instance, pinmux_type_t pinmux){
switch(instance)
{
case 0:
switch(pinmux)
{
case kPinmuxType_Default:
BW_PORT_PCRn_MUX(HW_PORTC, 8, 0);
BW_PORT_PCRn_MUX(HW_PORTC, 9, 0);
break;
case kPinmuxType_Peripheral:
// Enable pins for I2C0.
BW_PORT_PCRn_MUX(HW_PORTC, 8, 2); // I2C0_SCL is ALT2 for pin PTC8
BW_PORT_PCRn_MUX(HW_PORTC, 9, 2); // I2C0_SDA is ALT2 for pin PTC9
break;
default:
break;
}
break;
case 1:
break;
case 2:
break;
default:
break;
}
}
/* This function is called for configurating pinmux for spi module
* This function only support switching default or gpio or fixed-ALTx mode on fixed pins
* (Although there are many ALTx-pinmux configuration choices on various pins for the same
* peripheral module) */
void spi_pinmux_config(unsigned int instance, pinmux_type_t pinmux){
switch(instance)
{
case 0:
switch(pinmux)
{
case kPinmuxType_Default:
BW_PORT_PCRn_MUX(HW_PORTD, 0, 0);
BW_PORT_PCRn_MUX(HW_PORTD, 1, 0);
BW_PORT_PCRn_MUX(HW_PORTD, 2, 0);
BW_PORT_PCRn_MUX(HW_PORTD, 3, 0);
break;
case kPinmuxType_Peripheral:
// Enable pins for SPI0 on PTD0~3 (not available on 32-pin QFN package)
BW_PORT_PCRn_MUX(HW_PORTD, 0, 2); // SPI0_PCS0 is ALT2 for pin PTD0
BW_PORT_PCRn_MUX(HW_PORTD, 1, 2); // SPI0_SCK is ALT2 for pin PTD1
BW_PORT_PCRn_MUX(HW_PORTD, 2, 2); // SPI0_MOSI is ALT2 for pin PTD2
BW_PORT_PCRn_MUX(HW_PORTD, 3, 2); // SPI0_MISO is ALT2 for pin PTD3
break;
default:
break;
}
break;
case 1:
break;
case 2:
break;
default:
break;
}
}
void init_hardware(void){
SIM->SCGC5 |= ( SIM_SCGC5_PORTA_MASK
| SIM_SCGC5_PORTB_MASK
| SIM_SCGC5_PORTC_MASK
| SIM_SCGC5_PORTD_MASK
| SIM_SCGC5_PORTE_MASK );
SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK // set PLLFLLSEL to select the PLL for this clock source
| SIM_SOPT2_UART0SRC(1); // select the PLLFLLCLK as UART0 clock source
#if DEBUG
// Enable the pins for the debug UART1
BW_PORT_PCRn_MUX(HW_PORTC, 3, 3); // UART1_RX is PTC3 in ALT3
BW_PORT_PCRn_MUX(HW_PORTC, 4, 3); // UART1_TX is PTC4 in ALT3
#endif
}
void deinit_hardware(void){
SIM->SCGC5 &= (uint32_t)~( SIM_SCGC5_PORTA_MASK
| SIM_SCGC5_PORTB_MASK
| SIM_SCGC5_PORTC_MASK
| SIM_SCGC5_PORTD_MASK
| SIM_SCGC5_PORTE_MASK );
}
Przykładowa mapa pamięci dla mikrokontrolerów serii KL25Z128 zawarta jest w pliku memory_map_x.c i wygląda jak poniżej:
//! @brief Memory map for KL25Z128.
//!
//! This map is not const because it is updated at runtime with the actual sizes of
//! flash and RAM for the chip we're running on.
memory_map_entry_t g_memoryMap[] = {
{ 0x00000000, 0x0001ffff, &g_flashMemoryInterface }, // Flash array
{ 0x1ffff000, 0x20002fff, &g_normalMemoryInterface }, // SRAM (SRAM_L + SRAM_U)
{ 0x40000000, 0x4007ffff, &g_deviceMemoryInterface }, // AIPS peripherals
{ 0x400ff000, 0x400fffff, &g_deviceMemoryInterface }, // GPIO
{ 0x44000000, 0x5fffffff, &g_deviceMemoryInterface }, // BME
{ 0xe0000000, 0xe00fffff, &g_deviceMemoryInterface }, // M0+ private peripherals
{ 0xf0003000, 0xf0003fff, &g_deviceMemoryInterface }, // MCM
{ 0xf8000000, 0xffffffff, &g_deviceMemoryInterface }, // IOPORT (single-cycle GPIO)
{ 0 } // Terminator
};
Tablica deskryptorów, zdefiniowana w pliku peripherals_x.c, zawiera dane o rodzaju i numerze komunikacyjnych układów peryferyjnych dostępnych w mikrokontrolerze, a także wskaźniki na struktury opisujące kolejne warstwy architektury interfejsu peryferia (pod pojęciem interfejsu peryferia należy rozumieć zbiór środków w postaci funkcji, które umożliwiają pracę z układem peryferyjnym na poziomie od pojedynczych bajtów do rozbudowanych pakietów, bez wnikania w szczegóły implementacyjne tego układu) (rysunek 3). Ogólna struktura deskryptora peryferia jest następująca:
struct PeripheralDescriptor {
uint32_t typeMask;
uint32_t instance;
void (*pinmuxConfig)(uint32_t instance, pinmux_type_t pinmux);
const peripheral_control_interface_t *controlInterface;
const peripheral_byte_interface_t *byteInterface;
const peripheral_packet_interface_t *packetInterface;
};
Pole typeMask struktury może przyjmować jedną z poniższych wartości wskazujących rodzaj interfejsu komunikacyjnego:
- kPeripheralType_UART – wartość 1,
- kPeripheralType_I2CSlave – wartość 2,
- kPeripheralType_SPISlave – wartość 4,
- kPeripheralType_CAN – wartość 8,
- kPeripheralType_USB_HID – wartość 16,
- kPeripheralType_USB_CDC – wartość 32,
- kPeripheralType_USB_DFU – wartość 64,
- kPeripheralType_USB_MSC – wartość 128.

Technologie End of Life i bezpieczeństwo sieci – wyzwania Europy związane z tzw. długiem technologicznym
Najczęstsze błędy firm przy wyborze dostawcy energii i jak ich uniknąć
Fotorezystor, czyli czujnik światła dwojakiego działania. Przykład innowacji w automatyce i elektronice możliwej dzięki technologii fotooporników 



