diff --git a/Board.cpp b/Board.cpp index c28cb0f..2ff72fe 100644 --- a/Board.cpp +++ b/Board.cpp @@ -1,9 +1,10 @@ -/* - * File: Board.cpp - * Author: amr - * - * Created on July 30, 2025, 9:20 PM - */ +// © 2025 A.M. Rowsell + +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. #include "Board.hpp" diff --git a/Board.hpp b/Board.hpp index a721708..cf22035 100644 --- a/Board.hpp +++ b/Board.hpp @@ -1,9 +1,10 @@ -/* - * File: Board.hpp - * Author: amr - * - * Created on July 30, 2025, 9:20 PM - */ +// © 2025 A.M. Rowsell + +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. #ifndef BOARD_HPP #define BOARD_HPP diff --git a/NeoPixel.cpp b/NeoPixel.cpp index 695eefb..186eb47 100644 --- a/NeoPixel.cpp +++ b/NeoPixel.cpp @@ -1,13 +1,14 @@ -/* - * File: NeoPixel.cpp - * Author: amr - * - * Created on July 30, 2025, 9:35 PM - */ +// © 2025 A.M. Rowsell + +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. #include "NeoPixel.hpp" uint8_t setNeoPixel(uint8_t index, uint8_t red, uint8_t green, uint8_t blue) { - + return 0; } diff --git a/NeoPixel.hpp b/NeoPixel.hpp index fc3c407..b9e0d66 100644 --- a/NeoPixel.hpp +++ b/NeoPixel.hpp @@ -1,9 +1,10 @@ -/* - * File: NeoPixel.hpp - * Author: amr - * - * Created on July 30, 2025, 9:35 PM - */ +// © 2025 A.M. Rowsell + +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. #ifndef NEOPIXEL_HPP #define NEOPIXEL_HPP diff --git a/Piece.cpp b/Piece.cpp index cce8eae..e13db3d 100644 --- a/Piece.cpp +++ b/Piece.cpp @@ -1,9 +1,10 @@ -/* - * File: Piece.cpp - * Author: amr - * - * Created on July 30, 2025, 9:21 PM - */ +// © 2025 A.M. Rowsell + +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. #include "Piece.hpp" diff --git a/Piece.hpp b/Piece.hpp index 9987444..fe093a7 100644 --- a/Piece.hpp +++ b/Piece.hpp @@ -1,9 +1,10 @@ -/* - * File: Piece.hpp - * Author: amr - * - * Created on July 30, 2025, 9:21 PM - */ +// © 2025 A.M. Rowsell + +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// This Source Code Form is "Incompatible With Secondary Licenses", as +// defined by the Mozilla Public License, v. 2.0. #ifndef PIECE_HPP #define PIECE_HPP diff --git a/main.cpp b/main.cpp index 9625693..d25cd2d 100644 --- a/main.cpp +++ b/main.cpp @@ -6,10 +6,9 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. // This Source Code Form is "Incompatible With Secondary Licenses", as // defined by the Mozilla Public License, v. 2.0. + // PIC32MX270F256B Configuration Bit Settings - // 'C' source line config statements - // DEVCFG3 #pragma config USERID = 0xBEEF // Enter Hexadecimal value (Enter Hexadecimal value) #pragma config PMDL1WAY = OFF // Peripheral Module Disable Configuration (Allow multiple reconfigurations) @@ -61,6 +60,7 @@ volatile uint8_t spi_rx_buffer[8]; // dummy open to get rid of linker error + extern "C" int open(const char *buf, int flags, int mode) { // Always return failure — no file system. return -1; @@ -68,66 +68,67 @@ extern "C" int open(const char *buf, int flags, int mode) { void sendChar(uint8_t c) { U1TXREG = c; - while(!U1STAbits.TRMT); // wait for transmission + while (!U1STAbits.TRMT); // wait for transmission return; } uint8_t appInfo(uint8_t *msg, uint16_t len) { uint16_t offset = 0; do { - sendChar(*(msg+offset)); + sendChar(*(msg + offset)); offset++; - } while(--len); + } while (--len); return 0; } - /* - * Pin mapping: - * - * UART: (for debug) - * U1TX = RC0/pin 25 - * - * SPI: (to 74HC165) - * Shift/Load = RA0 - * Shift Clock SCK1 = RB14/pin 14 - * Data out SDI1 = RC8/pin 4 - * - * - * USB: - * RB10: D+ - * RB11: D- - * - * - */ +/* + * Pin mapping: + * + * UART: (for debug) + * U1TX = RC0/pin 25 + * + * SPI: (to 74HC165) + * Shift/Load = RA0 + * Shift Clock SCK1 = RB14/pin 14 + * Data out SDI1 = RC8/pin 4 + * + * + * USB: + * RB10: D+ + * RB11: D- + * + * + */ #define SL_TRIS TRISAbits.TRISA0 #define SL_LAT LATAbits.LATA0 + uint8_t initSystem(void) { /* set up GPIO */ SYSKEY = 0x0; SYSKEY = 0xAA996655; SYSKEY = 0x556699AA; - CFGCON &= ~(1<<13); // unlock PPS - + CFGCON &= ~(1 << 13); // unlock PPS + SDI1R = 0b0110; // RC8 RPC0R = 0b0001; // U1TX - + SYSKEY = 0x12345678; // lock SYSKEY ANSELACLR = 0xFFFF; // port A all digital SL_TRIS = 0; // RA0 as output SL_LAT = 1; // set high - + /* Set up SPI1 */ - SPI1CON = 0; // reset SPI config - SPI1BRG = (F_PER / (2 * SPI_BAUD)) - 1; // calculate for 1MHz - SPI1STATCLR = _SPI1STAT_SPIROV_MASK; // Clear overflow - SPI1CONbits.MSTEN = 1; // Enable Master mode - SPI1CONbits.CKP = 0; // Clock idle low - SPI1CONbits.CKE = 1; // Transmit on falling edge - SPI1CONbits.SMP = 1; // Input sampled at end - SPI1CONbits.ON = 1; // Enable SPI - + SPI1CON = 0; // reset SPI config + SPI1BRG = (F_PER / (2 * SPI_BAUD)) - 1; // calculate for 1MHz + SPI1STATCLR = _SPI1STAT_SPIROV_MASK; // Clear overflow + SPI1CONbits.MSTEN = 1; // Enable Master mode + SPI1CONbits.CKP = 0; // Clock idle low + SPI1CONbits.CKE = 1; // Transmit on falling edge + SPI1CONbits.SMP = 1; // Input sampled at end + SPI1CONbits.ON = 1; // Enable SPI + /* set up UART */ U1BRG = 19; // 9600 baud (was 38 @ 24MHz) U1STAbits.UTXEN = 1; // enable transmitter @@ -137,50 +138,50 @@ uint8_t initSystem(void) { // clear all 4 DMA channel flags & IE IEC1CLR = 0xF0000000; IFS1CLR = 0xF0000000; - + DMACONbits.ON = 1; //enable DMA controller - + // === DMA Channel 1 Init (RX from SPI1BUF to spi_rx_buffer[]) === - DCH0CON = 0; // Reset channel config + DCH0CON = 0; // Reset channel config DCH0ECON = 0; - DCH0SSA = KVA_TO_PA(&SPI1BUF); // Source: SPI1BUF - DCH0DSA = KVA_TO_PA(spi_rx_buffer); // Destination: receive buffer - DCH0SSIZ = 1; // Source size = 1 byte - DCH0DSIZ = sizeof(spi_rx_buffer); // Destination size = 8 bytes - DCH0CSIZ = 1; // Cell transfer size = 1 byte + DCH0SSA = KVA_TO_PA(&SPI1BUF); // Source: SPI1BUF + DCH0DSA = KVA_TO_PA(spi_rx_buffer); // Destination: receive buffer + DCH0SSIZ = 1; // Source size = 1 byte + DCH0DSIZ = sizeof (spi_rx_buffer); // Destination size = 8 bytes + DCH0CSIZ = 1; // Cell transfer size = 1 byte - DCH0ECONbits.CHSIRQ = _SPI1_VECTOR; // Trigger on SPI1 receive - DCH0ECONbits.SIRQEN = 1; // Enable IRQ trigger + DCH0ECONbits.CHSIRQ = _SPI1_VECTOR; // Trigger on SPI1 receive + DCH0ECONbits.SIRQEN = 1; // Enable IRQ trigger - DCH0INTCLR = 0x00FF00FF; // Clear all interrupt flags - DCH0INTbits.CHBCIE = 1; // Enable block complete interrupt + DCH0INTCLR = 0x00FF00FF; // Clear all interrupt flags + DCH0INTbits.CHBCIE = 1; // Enable block complete interrupt - DCH0CONbits.CHPRI = 2; // Priority 2 (TX is higher) - DCH0CONbits.CHAEN = 1; // Auto-enable on trigger - DCH0CONbits.CHEN = 1; // Enable channel + DCH0CONbits.CHPRI = 2; // Priority 2 (TX is higher) + DCH0CONbits.CHAEN = 1; // Auto-enable on trigger + DCH0CONbits.CHEN = 1; // Enable channel return 0; } void initInterrupts(void) { - INTCONbits.MVEC = 1; // Enable multi-vector interrupts + INTCONbits.MVEC = 1; // Enable multi-vector interrupts __builtin_enable_interrupts(); - IPC10bits.DMA0IP = 3; // Priority level 3 - IFS1CLR = _IFS1_DMA0IF_MASK; // Clear interrupt flag - IEC1SET = _IEC1_DMA0IE_MASK; // Enable DMA1 interrupt + IPC10bits.DMA0IP = 3; // Priority level 3 + IFS1CLR = _IFS1_DMA0IF_MASK; // Clear interrupt flag + IEC1SET = _IEC1_DMA0IE_MASK; // Enable DMA1 interrupt } void startSPI_DMA_Transfer(void) { // Pulse PL low to latch inputs from 74HC165 SL_LAT = 0; - asm volatile("nop; nop; nop;"); // small delay + asm volatile("nop; nop; nop;"); // small delay SL_LAT = 1; DCH0CONbits.CHEN = 1; for (int i = 0; i < 8; i++) { - while (SPI1STATbits.SPITBF); // Wait if TX buffer full - SPI1BUF = 0x00; // Send dummy byte to clock in data + while (SPI1STATbits.SPITBF); // Wait if TX buffer full + SPI1BUF = 0x00; // Send dummy byte to clock in data } return; } @@ -190,19 +191,20 @@ extern "C" int main(void) { initInterrupts(); Board gameBoard; NeoPixel boardLights(64); - - while(1) { - + + while (1) { + } } // === Interrupt Service Routine for DMA0 (RX complete) === + extern "C" void __ISR(_DMA0_VECTOR, IPL3SOFT) DMA0Handler(void) { __builtin_disable_interrupts(); // stop additional ints from firing if (DCH0INTbits.CHBCIF) { - DCH0INTCLR = _DCH0INT_CHBCIF_MASK; // Clear block complete flag + DCH0INTCLR = _DCH0INT_CHBCIF_MASK; // Clear block complete flag // DMA RX completed — spi_rx_buffer[] now contains the data } - IFS1CLR = _IFS1_DMA0IF_MASK; // Clear global DMA0 IRQ flag + IFS1CLR = _IFS1_DMA0IF_MASK; // Clear global DMA0 IRQ flag } \ No newline at end of file