summaryrefslogtreecommitdiffstats
path: root/hal
diff options
context:
space:
mode:
authorNao Pross <naopross@thearcway.org>2018-05-04 18:27:12 +0200
committerNao Pross <naopross@thearcway.org>2018-05-04 18:27:12 +0200
commit5e8e628da03121323351e54e6866826288e4c4bd (patch)
tree4b3476cec9c295b5c633ea6b801815a131e2780b /hal
parentAdd templated generic implementaions for uart, rename uart1.tpp to uart.tpp (diff)
downloadSAMLiquidSmoke-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.hpp39
-rw-r--r--hal/hwconfig.cpp39
-rw-r--r--hal/hwconfig.hpp22
-rw-r--r--hal/pin.hpp5
-rw-r--r--hal/pin.tpp20
-rw-r--r--hal/uart.hpp14
-rw-r--r--hal/uart.tpp102
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