diff options
author | Nao Pross <naopross@thearcway.org> | 2018-05-04 18:27:12 +0200 |
---|---|---|
committer | Nao Pross <naopross@thearcway.org> | 2018-05-04 18:27:12 +0200 |
commit | 5e8e628da03121323351e54e6866826288e4c4bd (patch) | |
tree | 4b3476cec9c295b5c633ea6b801815a131e2780b /hal | |
parent | Add templated generic implementaions for uart, rename uart1.tpp to uart.tpp (diff) | |
download | SAMLiquidSmoke-5e8e628da03121323351e54e6866826288e4c4bd.tar.gz SAMLiquidSmoke-5e8e628da03121323351e54e6866826288e4c4bd.zip |
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.
Diffstat (limited to 'hal')
-rw-r--r-- | hal/confbits.hpp | 39 | ||||
-rw-r--r-- | hal/hwconfig.cpp | 39 | ||||
-rw-r--r-- | hal/hwconfig.hpp | 22 | ||||
-rw-r--r-- | hal/pin.hpp | 5 | ||||
-rw-r--r-- | hal/pin.tpp | 20 | ||||
-rw-r--r-- | hal/uart.hpp | 14 | ||||
-rw-r--r-- | hal/uart.tpp | 102 |
7 files changed, 208 insertions, 33 deletions
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 <xc.h> +} + +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 <xc.h> +} + + template<unsigned bit> 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<unsigned bit> void pin<bit>::set_mode(unsigned m) { if (m) - *_tris |= 1<<bit; + *_tris |= 1<<bit; // input else - *_tris &= ~(1<<bit); + *_tris &= ~(1<<bit); // output } template<unsigned bit> void pin<bit>::set_mode(pin<bit>::mode m) { - set(static_cast<unsigned>(m)); + set_mode(static_cast<unsigned>(m)); } template<unsigned bit> typename pin<bit>::state pin<bit>::read() const { - if (*_tris & (1<<bit)) + if (*_port & (1<<bit)) return state::ON; else return state::OFF; @@ -55,10 +57,10 @@ typename pin<bit>::state pin<bit>::read() const template<unsigned bit> void pin<bit>::set(unsigned s) { - if (s) - *_latch |= 1<<bit; + if (s > 0) + *_latch |= 1<<bit; // on else - *_latch &= ~(1<<bit); + *_latch &= ~(1<<bit); // off } template<unsigned bit> @@ -86,3 +88,5 @@ bool pin<bit>::operator!=(const pin<bit> &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 <cstdint> #include <cstddef> -#include <string> +#include <queue> 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<uint8_t> rx_buffer[devices_count]; + std::queue<uint8_t> tx_buffer[devices_count]; template<unsigned dev> void initialize(); template<unsigned dev> - uint8_t peek(uint16_t offset); - - template<unsigned dev> - uint8_t read(void); + uint8_t read(); template<unsigned dev> unsigned read(uint8_t *buffer, const unsigned numbytes); @@ -62,6 +59,9 @@ namespace uart void write(const uint8_t byte); template<unsigned dev> + void write(const std::string &str); + + template<unsigned dev> unsigned write(const uint8_t *buffer, const unsigned numbytes); template<unsigned dev> 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 <proc/p32mx470f512h.h> +// #include <proc/p32mx470f512h.h> +#include <xc.h> #include <sys/attribs.h> } @@ -17,36 +26,81 @@ extern "C" { namespace uart { template<unsigned dev> - uint8_t peek<dev>(uint16_t offset) + bool rx_buffer_empty() + { + return rx_buffer[dev -1].empty(); + } + + template<unsigned dev> + 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<unsigned dev> - bool rx_buffer_empty<dev>() + 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 dev> + unsigned read(uint8_t *buffer, const unsigned numbytes) + { + uint8_t *bptr = buffer; + unsigned len = numbytes; + + while (len--) { + *(bptr++) = read<dev>(); + } + } + + template<unsigned dev> + void write(const uint8_t byte) + { + } template<unsigned dev> - bool tx_buffer_full<dev>() + void write(const std::string &str) { - return !tx_buffer[0].empty(); + for (const char &c : str) { + write<dev>(c); + } + } + + template<unsigned dev> + 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<uint8_t>(U1RXREG)); + // debug + led_blue.toggle(); + while (U1STAbits.URXDA) { + uart::rx_buffer[0].push(static_cast<uint8_t>(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 |