From 5e8e628da03121323351e54e6866826288e4c4bd Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Fri, 4 May 2018 18:27:12 +0200 Subject: Implement most of basic HAL Oscillator: The oscillator is configured correctly. Interrupts: RX uart interrupts work. The global interrupt vector table is enabled. UART: RX features work. --- hal/confbits.hpp | 39 +++++++++++++++++++++ hal/hwconfig.cpp | 39 +++++++++++++++++++++ hal/hwconfig.hpp | 22 ++++++++++++ hal/pin.hpp | 5 +++ hal/pin.tpp | 20 ++++++----- hal/uart.hpp | 14 ++++---- hal/uart.tpp | 102 +++++++++++++++++++++++++++++++++++++++++++++---------- 7 files changed, 208 insertions(+), 33 deletions(-) create mode 100644 hal/confbits.hpp create mode 100644 hal/hwconfig.cpp create mode 100644 hal/hwconfig.hpp (limited to 'hal') diff --git a/hal/confbits.hpp b/hal/confbits.hpp new file mode 100644 index 0000000..9af7023 --- /dev/null +++ b/hal/confbits.hpp @@ -0,0 +1,39 @@ +#ifndef CONFBITS_HPP +#define CONFBITS_HPP + +// DEVCFG3 +#pragma config FSRSSEL = PRIORITY_7 // Shadow Register Set Priority Select->SRS Priority 7 +#pragma config PMDL1WAY = ON // Peripheral Module Disable Configuration->Allow only one reconfiguration +#pragma config IOL1WAY = ON // Peripheral Pin Select Configuration->Allow only one reconfiguration +#pragma config FUSBIDIO = ON // USB USID Selection->Controlled by the USB Module +#pragma config FVBUSONIO = ON // USB VBUS ON Selection->Controlled by USB Module + +// DEVCFG2 +#pragma config FPLLIDIV = DIV_12 // PLL Input Divider->12x Divider +#pragma config FPLLMUL = MUL_24 // PLL Multiplier->24x Multiplier +#pragma config UPLLIDIV = DIV_12 // USB PLL Input Divider->12x Divider +#pragma config UPLLEN = OFF // USB PLL Enable->Disabled and Bypassed +#pragma config FPLLODIV = DIV_256 // System PLL Output Clock Divider->PLL Divide by 256 + +// DEVCFG1 +#pragma config FNOSC = FRCDIV // Oscillator Selection Bits->Fast RC Osc w/Div-by-N (FRCDIV) +#pragma config FSOSCEN = ON // Secondary Oscillator Enable->Enabled +#pragma config IESO = ON // Internal/External Switch Over->Enabled +#pragma config POSCMOD = OFF // Primary Oscillator Configuration->Primary osc disabled +#pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin->Disabled +#pragma config FPBDIV = DIV_8 // Peripheral Clock Divisor->Pb_Clk is Sys_Clk/8 +#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection->Clock Switch Disable, FSCM Disabled +#pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler->1:1048576 +#pragma config WINDIS = OFF // Watchdog Timer Window Enable->Watchdog Timer is in Non-Window Mode +#pragma config FWDTEN = OFF // Watchdog Timer Enable->WDT Disabled (SWDTEN Bit Controls) +#pragma config FWDTWINSZ = WINSZ_25 // Watchdog Timer Window Size->Window Size is 25% + +// DEVCFG0 +#pragma config DEBUG = OFF // Background Debugger Enable->Debugger is Disabled +#pragma config JTAGEN = ON // JTAG Enable->JTAG Port Enabled +#pragma config ICESEL = ICS_PGx1 // ICE/ICD Comm Channel Select->Communicate on PGEC1/PGED1 +#pragma config PWP = OFF // Program Flash Write Protect->Disable +#pragma config BWP = OFF // Boot Flash Write Protect bit->Protection Disabled +#pragma config CP = OFF // Code Protect->Protection Disabled + +#endif \ No newline at end of file diff --git a/hal/hwconfig.cpp b/hal/hwconfig.cpp new file mode 100644 index 0000000..a3b4b46 --- /dev/null +++ b/hal/hwconfig.cpp @@ -0,0 +1,39 @@ +#include "hwconfig.hpp" + +extern "C" { +#include +} + +void hw::reglock() +{ + SYSKEY = 0x00000000; +} + +void hw::regunlock() +{ + SYSKEY = 0x12345678; + SYSKEY = 0xAA996655; + SYSKEY = 0x556699AA; +} + +void osc::initialize() +{ + hw::regunlock(); + // CF no clock failure; COSC FRCDIV; PLLODIV DIV_256; UFRCEN disabled; PBDIVRDY disabled; SLOCK out of lock; FRCDIV FRC/1; SLPEN Idle on WAIT instruction; NOSC FRCDIV; PLLMULT MUL_24; SOSCEN disabled; PBDIV DIV_8; CLKLOCK unlocked; OSWEN Switch is Complete; SOSCRDY disabled; + OSCCON = 0x381F7700; + hw::reglock(); + // TUN Center Frequency; + OSCTUN = 0x0; + // DIVSWEN disabled; RSLP disabled; ACTIVE Active; ROSEL SYSCLK; OE Not Driven out on REFCLKO pin; SIDL disabled; RODIV 0; ON disabled; + REFOCON = 0x100; + // ROTRIM 0; + REFOTRIM = 0x0; +} + +void interrupts::initialize() +{ + // Enable the multi vector + INTCONbits.MVEC = 1; + // Enable Global Interrupts + __builtin_mtc0(12,0,(__builtin_mfc0(12,0) | 0x0001)); +} \ No newline at end of file diff --git a/hal/hwconfig.hpp b/hal/hwconfig.hpp new file mode 100644 index 0000000..0cd38ac --- /dev/null +++ b/hal/hwconfig.hpp @@ -0,0 +1,22 @@ +#ifndef HWCONFIG_HPP +#define HWCONFIG_HPP + +#define _XTAL_FREQ 8000000UL + +namespace hw +{ + void reglock(); + void regunlock(); +} + +namespace osc +{ + void initialize(); +} + +namespace interrupts +{ + void initialize(); +} + +#endif \ No newline at end of file diff --git a/hal/pin.hpp b/hal/pin.hpp index 384c0c7..ff131ef 100644 --- a/hal/pin.hpp +++ b/hal/pin.hpp @@ -8,6 +8,11 @@ #ifndef PIN_HPP #define PIN_HPP +extern "C" { +#include +} + + template class pin { public: diff --git a/hal/pin.tpp b/hal/pin.tpp index c6cf957..3954945 100644 --- a/hal/pin.tpp +++ b/hal/pin.tpp @@ -1,10 +1,12 @@ /* - * File: pin.cpp + * File: pin.tpp * Author: naopross * * Created on May 3, 2018, 8:02 PM */ +#ifndef PIN_TPP +#define PIN_TPP #include "pin.hpp" @@ -32,21 +34,21 @@ template void pin::set_mode(unsigned m) { if (m) - *_tris |= 1< void pin::set_mode(pin::mode m) { - set(static_cast(m)); + set_mode(static_cast(m)); } template typename pin::state pin::read() const { - if (*_tris & (1<::state pin::read() const template void pin::set(unsigned s) { - if (s) - *_latch |= 1< 0) + *_latch |= 1< @@ -86,3 +88,5 @@ bool pin::operator!=(const pin &other) const { return !(*this == other); } + +#endif \ No newline at end of file diff --git a/hal/uart.hpp b/hal/uart.hpp index 461f0fa..096ac7b 100644 --- a/hal/uart.hpp +++ b/hal/uart.hpp @@ -10,7 +10,7 @@ #include #include -#include +#include extern "C" { void usart_1_isr(); @@ -43,17 +43,14 @@ namespace uart tx_empty = 1<<4, }; - std::string rx_buffer[devices_count]; - std::string tx_buffer[devices_count]; + std::queue rx_buffer[devices_count]; + std::queue tx_buffer[devices_count]; template void initialize(); template - uint8_t peek(uint16_t offset); - - template - uint8_t read(void); + uint8_t read(); template unsigned read(uint8_t *buffer, const unsigned numbytes); @@ -61,6 +58,9 @@ namespace uart template void write(const uint8_t byte); + template + void write(const std::string &str); + template unsigned write(const uint8_t *buffer, const unsigned numbytes); diff --git a/hal/uart.tpp b/hal/uart.tpp index 44d9315..8c120ec 100644 --- a/hal/uart.tpp +++ b/hal/uart.tpp @@ -1,14 +1,23 @@ /* - * File: uart.cpp + * File: uart.tpp * Author: naopross * * Created on May 2, 2018, 7:05 PM + * + * Note: Templated functions cannot be created outside of a namespace definition + * because of a g++ bug in version 4.8.0 on which xc++ is based. + * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480 */ +#ifndef UART_TPP +#define UART_TPP + +#include "hwconfig.hpp" #include "uart.hpp" extern "C" { -#include +// #include +#include #include } @@ -17,36 +26,81 @@ extern "C" { namespace uart { template - uint8_t peek(uint16_t offset) + bool rx_buffer_empty() + { + return rx_buffer[dev -1].empty(); + } + + template + bool tx_buffer_full() { - if (offset >= rx_buffer[dev -1].size()) - return 0; - else - return rx_buffer[dev -1].at(offset); + return !tx_buffer[dev -1].empty(); } template - bool rx_buffer_empty() + uint8_t read() { - return rx_buffer[0].empty(); + uint8_t byte = rx_buffer[dev -1].front(); + rx_buffer[dev -1].pop(); + + return byte; + } + + template + unsigned read(uint8_t *buffer, const unsigned numbytes) + { + uint8_t *bptr = buffer; + unsigned len = numbytes; + + while (len--) { + *(bptr++) = read(); + } + } + + template + void write(const uint8_t byte) + { + } template - bool tx_buffer_full() + void write(const std::string &str) { - return !tx_buffer[0].empty(); + for (const char &c : str) { + write(c); + } + } + + template + unsigned write(const uint8_t *buffer, const unsigned numbytes) + { + } } -/* specialization for UART1 */ +/* specializations for UART1 */ + +// debug +#include "pin.tpp" +pin<2> led_blue(&LATBbits, &TRISBbits, &PORTEbits); + void __ISR(_UART_1_VECTOR, IPL1AUTO) usart_1_isr() { if (IFS1bits.U1RXIF) { - uart::rx_buffer[0].push_back(static_cast(U1RXREG)); + // debug + led_blue.toggle(); + while (U1STAbits.URXDA) { + uart::rx_buffer[0].push(static_cast(U1RXREG)); + } IFS1bits.U1RXIF = 0; } else if (IFS1bits.U1TXIF) { + IFS1bits.U1TXIF = 0; + } else { + if (U1STAbits.OERR == 1) { + U1STAbits.OERR = 0; + } IFS1bits.U1TXIF = 0; } @@ -93,13 +147,25 @@ namespace uart U1STAbits.UTXEN = 1; U1STAbits.URXEN = 1; - //Enabling UART + // Enabling UART U1MODEbits.ON = 1; - } - template<> - uint8_t read<1>() - { + // UERI: UART1 Error + // Priority: 1 + // SubPriority: 0 + IPC7bits.U1IP = 1; + IPC7bits.U1IS = 0; + // map uart pins to port F + hw::regunlock(); // unlock PPS + CFGCONbits.IOLOCK = 0; + + U1RXRbits.U1RXR = 0x0004; //RF1->UART1:U1RX; + RPF0Rbits.RPF0R = 0x0003; //RF0->UART1:U1TX; + + CFGCONbits.IOLOCK = 1; // lock PPS + hw::reglock(); } } + +#endif \ No newline at end of file -- cgit v1.2.1