Renamed .h files, formatted all code with astyle -A14

I now have a post-build step which formats all the code using
astyle -n -z2 -Z -A14 *.hpp *.cpp
The options are to preserve the dates of each file, force the
Linux line endings, and format the files directly omitting the
creation of the .orig file. The -A14 is "Google" style which
happens to be the style I've always personally used, which is
handy.
This commit is contained in:
A.M. Rowsell 2020-10-06 12:01:34 -04:00
parent d9b5b15b96
commit f8eab9ebd9
Signed by: amr
GPG Key ID: 0B6E2D8375CF79A9
10 changed files with 343 additions and 344 deletions

View File

@ -1,7 +1,7 @@
/* /*
* File: FIFO.cpp * File: FIFO.cpp
* Author: amr * Author: amr
* *
* Created on October 1, 2020, 4:58 PM * Created on October 1, 2020, 4:58 PM
*/ */

View File

@ -1,4 +1,4 @@
/* /*
* File: FIFO.hpp * File: FIFO.hpp
* Author: amr * Author: amr
* *
@ -12,7 +12,7 @@
#include <stdlib.h> #include <stdlib.h>
class FIFO { class FIFO {
public: public:
FIFO(int size); FIFO(int size);
uint8_t read(void); uint8_t read(void);
uint8_t write(uint8_t item); uint8_t write(uint8_t item);
@ -21,7 +21,7 @@ public:
int writeIndex = 0; int writeIndex = 0;
int usedSize = 0; int usedSize = 0;
uint8_t *fifoBuffer; uint8_t *fifoBuffer;
private: private:
}; };

View File

@ -1,7 +1,7 @@
/* /*
* File: FlashStorage.cpp * File: FlashStorage.cpp
* Author: amr * Author: amr
* *
* Created on October 1, 2020, 5:03 PM * Created on October 1, 2020, 5:03 PM
*/ */
@ -32,17 +32,14 @@ uint8_t FlashStorage::readStatusRegister(void) {
while(!(SPI1STAT & 0x01)); // wait for byte while(!(SPI1STAT & 0x01)); // wait for byte
statusReg = SPI1BUF; statusReg = SPI1BUF;
PORTASET = 0x10; PORTASET = 0x10;
if(statusReg & 0x01) { if(statusReg & 0x01) {
return FLASH_BUSY; return FLASH_BUSY;
} } else if(statusReg & 0x20) {
else if(statusReg & 0x20) {
return FLASH_ERASE_ERROR; return FLASH_ERASE_ERROR;
} } else if(statusReg & 0x40) {
else if(statusReg & 0x40) {
return FLASH_PROG_ERROR; return FLASH_PROG_ERROR;
} } else {
else {
return FLASH_OKAY; return FLASH_OKAY;
} }
} }
@ -65,7 +62,7 @@ void FlashStorage::sectorErase(uint8_t sector) {
// we need to wait for the erase // we need to wait for the erase
while(readStatusRegister() != FLASH_OKAY) ; while(readStatusRegister() != FLASH_OKAY) ;
// this might end up crashing if there's an error, but... whatever // this might end up crashing if there's an error, but... whatever
} }
uint8_t FlashStorage::read(uint32_t addr, uint32_t length) { uint8_t FlashStorage::read(uint32_t addr, uint32_t length) {
@ -92,7 +89,7 @@ uint8_t FlashStorage::read(uint32_t addr, uint32_t length) {
return 0; return 0;
} }
} }
PORTASET = 0x10; // set CS high PORTASET = 0x10; // set CS high
return length; return length;
} }
@ -109,12 +106,12 @@ uint8_t FlashStorage::write(uint32_t addr, uint32_t length, uint8_t *data) {
SPI1BUF = (uint8_t)((addr >> 8) & 0x000000FF); SPI1BUF = (uint8_t)((addr >> 8) & 0x000000FF);
while(SPI1STAT & 0x02); while(SPI1STAT & 0x02);
SPI1BUF = (uint8_t)((addr) & 0x000000FF); SPI1BUF = (uint8_t)((addr) & 0x000000FF);
for(uint32_t i = 0; i < length; i++) { for(uint32_t i = 0; i < length; i++) {
while(SPI1STAT & 0x02); while(SPI1STAT & 0x02);
SPI1BUF = *(data + i); SPI1BUF = *(data + i);
} }
PORTASET = 0x10; // set CS high PORTASET = 0x10; // set CS high
while(readStatusRegister() != FLASH_OKAY) ; // wait for programming while(readStatusRegister() != FLASH_OKAY) ; // wait for programming
return 0; return 0;
@ -130,7 +127,7 @@ uint8_t FlashStorage::program(void) {
sectorErase(0); sectorErase(0);
sectorErase(1); sectorErase(1);
sectorErase(2); sectorErase(2);
while(1) { while(1) {
length = 0; length = 0;
serial->send(readySend); serial->send(readySend);
@ -142,5 +139,5 @@ uint8_t FlashStorage::program(void) {
curAddr += 64; curAddr += 64;
} }
free(progBuffer); free(progBuffer);
return 0; return 0;
} }

View File

@ -1,4 +1,4 @@
/* /*
* File: FlashStorage.hpp * File: FlashStorage.hpp
* Author: amr * Author: amr
* *
@ -20,14 +20,14 @@
#define FLASH_ERASE_ERROR 3 #define FLASH_ERASE_ERROR 3
class FlashStorage { class FlashStorage {
public: public:
FlashStorage(FIFO *fifobuffer, UART *serialBus); FlashStorage(FIFO *fifobuffer, UART *serialBus);
uint8_t readStatusRegister(void); uint8_t readStatusRegister(void);
void sectorErase(uint8_t sector); void sectorErase(uint8_t sector);
uint8_t read(uint32_t addr, uint32_t length); uint8_t read(uint32_t addr, uint32_t length);
uint8_t write(uint32_t addr, uint32_t length, uint8_t *data); uint8_t write(uint32_t addr, uint32_t length, uint8_t *data);
uint8_t program(void); uint8_t program(void);
private: private:
FIFO *buffer; FIFO *buffer;
UART *serial; UART *serial;
void enableFlashWrite(void); void enableFlashWrite(void);

View File

@ -1,7 +1,7 @@
/* /*
* File: UART.cpp * File: UART.cpp
* Author: amr * Author: amr
* *
* Created on October 2, 2020, 5:51 PM * Created on October 2, 2020, 5:51 PM
*/ */
@ -12,7 +12,7 @@ UART::UART(uint32_t baud, uint32_t clockSpeed) {
uint16_t ibaud = 0; uint16_t ibaud = 0;
cbaud = ((double)clockSpeed/((double)baud*16.0)) - 1.0; cbaud = ((double)clockSpeed/((double)baud*16.0)) - 1.0;
ibaud = (uint16_t)(cbaud - 0.5); ibaud = (uint16_t)(cbaud - 0.5);
U1BRG = ibaud; U1BRG = ibaud;
U1STAbits.UTXEN = 1; // enable transmitter U1STAbits.UTXEN = 1; // enable transmitter
U1STAbits.URXEN = 1; // enable receiver U1STAbits.URXEN = 1; // enable receiver

View File

@ -1,4 +1,4 @@
/* /*
* File: UART.hpp * File: UART.hpp
* Author: amr * Author: amr
* *
@ -11,11 +11,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <xc.h> #include <xc.h>
class UART { class UART {
public: public:
UART(uint32_t baud, uint32_t clockSpeed); UART(uint32_t baud, uint32_t clockSpeed);
void send(uint8_t c); void send(uint8_t c);
uint8_t receive(void); uint8_t receive(void);
private: private:
}; };

View File

@ -1,4 +1,4 @@
/* /*
* File: fuses.h * File: fuses.h
* Author: amr * Author: amr
* *

358
i2c.cpp
View File

@ -1,5 +1,5 @@
/** @file i2c.cpp /** @file i2c.cpp
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
@ -11,7 +11,7 @@
* @fn i2c::i2c * @fn i2c::i2c
* @param speed the requested I2C bus speed * @param speed the requested I2C bus speed
* @param pclk the speed of the peripheral clock * @param pclk the speed of the peripheral clock
* *
* This constructor takes the requested bus speed and the peripheral * This constructor takes the requested bus speed and the peripheral
* clock speed, and calculates the appropriate baud rate divisor for * clock speed, and calculates the appropriate baud rate divisor for
* I2C2BRG. Then it enables the I2C module. * I2C2BRG. Then it enables the I2C module.
@ -31,12 +31,12 @@ i2c::i2c(uint32_t speed, uint32_t pclk) {
* @param recv buffer for data to be received, can be NULL * @param recv buffer for data to be received, can be NULL
* @param size number of bytes to send to received * @param size number of bytes to send to received
* @param mode which transactMode to use * @param mode which transactMode to use
* @param memAddr optional memory address, only used when communicating with * @param memAddr optional memory address, only used when communicating with
* EEPROMs, can be NULL if not needed. This is a pointer to the variable * EEPROMs, can be NULL if not needed. This is a pointer to the variable
* holding the memory address. This is done so that it can be NULL * holding the memory address. This is done so that it can be NULL
* when not needed. * when not needed.
* @return a status code, not fully implemented * @return a status code, not fully implemented
* *
* Note that the address needs to be sent in 7-bit mode * Note that the address needs to be sent in 7-bit mode
* Note also that null pointers can be used when a mode * Note also that null pointers can be used when a mode
* doesn't require use of one of the pointers * doesn't require use of one of the pointers
@ -52,48 +52,87 @@ i2c::i2c(uint32_t speed, uint32_t pclk) {
* 2: NACK on data * 2: NACK on data
*/ */
uint8_t i2c::transact(uint8_t addr, uint8_t *send, uint8_t *recv, \ uint8_t i2c::transact(uint8_t addr, uint8_t *send, uint8_t *recv, \
uint8_t size, transactMode mode, uint16_t *memAddr) { uint8_t size, transactMode mode, uint16_t *memAddr) {
uint8_t fullAddress, status = 0; uint8_t fullAddress, status = 0;
uint8_t loopVar; uint8_t loopVar;
const int max = 255; const int max = 255;
const int prime = 317; const int prime = 317;
switch (mode) { switch (mode) {
case SINGLE_SEND: // Single send case SINGLE_SEND: // Single send
fullAddress = addr << 1; // we are writing, thus R/W = 0 fullAddress = addr << 1; // we are writing, thus R/W = 0
while (I2C2STATbits.TRSTAT); // wait for any transmission to finish while (I2C2STATbits.TRSTAT); // wait for any transmission to finish
I2C2CONbits.SEN = 1; // send a start I2C2CONbits.SEN = 1; // send a start
while (I2C2CONbits.SEN); // wait for start to complete while (I2C2CONbits.SEN); // wait for start to complete
I2C2TRN = fullAddress; // send address I2C2TRN = fullAddress; // send address
while (I2C2STATbits.TRSTAT); // wait for transmission
if (I2C2STATbits.ACKSTAT == 0) {
// acknowledge received
} else {
status |= 1; // NACK on address
}
if(memAddr != NULL) {
// Send memory address
I2C2TRN = (uint8_t)(*memAddr >> 8);
while (I2C2STATbits.TRSTAT); // wait for transmission
I2C2TRN = (uint8_t)(*memAddr & 0x00FF);
while (I2C2STATbits.TRSTAT); // wait for transmission
}
if(send != NULL) {
// Now send the actual data
I2C2TRN = *send; // load buffer with data
while (I2C2STATbits.TRSTAT); // wait for transmission while (I2C2STATbits.TRSTAT); // wait for transmission
if (I2C2STATbits.ACKSTAT == 0) { if (I2C2STATbits.ACKSTAT == 0) {
// acknowledge received // acknowledge received
} else { } else {
status |= 1; // NACK on address status |= 2; // NACK on data
} }
if(memAddr != NULL) { } else {
// Send memory address status |= NULL_ERROR;
I2C2TRN = (uint8_t)(*memAddr >> 8); }
while (I2C2STATbits.TRSTAT); // wait for transmission I2C2CONbits.PEN = 1; // send STOP
I2C2TRN = (uint8_t)(*memAddr & 0x00FF); while (I2C2CONbits.PEN); // wait for stop to complete
while (I2C2STATbits.TRSTAT); // wait for transmission break;
} case MULTIPLE_SEND: // Multiple send
if(send != NULL) { fullAddress = addr << 1; // we are writing, thus R/W = 0
// Now send the actual data while (I2C2STATbits.TRSTAT); // wait for any transmission to finish
I2C2TRN = *send; // load buffer with data I2C2CONbits.SEN = 1; // send a start
while (I2C2CONbits.SEN); // wait for start to complete
I2C2TRN = fullAddress; // send address
while (I2C2STATbits.TRSTAT); // wait for transmission
if (I2C2STATbits.ACKSTAT == 0) {
// acknowledge received
} else {
status |= 1; // NACK on address
}
if(memAddr != NULL) {
// Send memory address
I2C2TRN = (uint8_t)(*memAddr >> 8);
while (I2C2STATbits.TRSTAT); // wait for transmission
I2C2TRN = (uint8_t)(*memAddr & 0x00FF);
while (I2C2STATbits.TRSTAT); // wait for transmission
}
if(send != NULL) { // guard against NULL pointer
// Now send the actual data
for (loopVar = size; loopVar > 0; loopVar--) { // do until size hits zero
I2C2TRN = *send; // load buffer with (next) data
while (I2C2STATbits.TRSTAT); // wait for transmission while (I2C2STATbits.TRSTAT); // wait for transmission
if (I2C2STATbits.ACKSTAT == 0) { if (I2C2STATbits.ACKSTAT == 0) {
// acknowledge received // acknowledge received
} else { } else {
status |= 2; // NACK on data status |= 2; // NACK on data
} }
} else { send++; // good old pointer increment... hope it works!
status |= NULL_ERROR;
} }
I2C2CONbits.PEN = 1; // send STOP } else {
while (I2C2CONbits.PEN); // wait for stop to complete status |= NULL_ERROR;
break; }
case MULTIPLE_SEND: // Multiple send I2C2CONbits.PEN = 1; // send STOP
while (I2C2CONbits.PEN); // wait for stop to complete
break;
case SINGLE_RECV: // Single receive
if(memAddr != NULL || send != NULL) {
fullAddress = addr << 1; // we are writing, thus R/W = 0 fullAddress = addr << 1; // we are writing, thus R/W = 0
while (I2C2STATbits.TRSTAT); // wait for any transmission to finish while (I2C2STATbits.TRSTAT); // wait for any transmission to finish
I2C2CONbits.SEN = 1; // send a start I2C2CONbits.SEN = 1; // send a start
@ -105,168 +144,129 @@ uint8_t i2c::transact(uint8_t addr, uint8_t *send, uint8_t *recv, \
} else { } else {
status |= 1; // NACK on address status |= 1; // NACK on address
} }
if(memAddr != NULL) { }
// Send memory address if(memAddr != NULL) {
I2C2TRN = (uint8_t)(*memAddr >> 8); // Send memory address
while (I2C2STATbits.TRSTAT); // wait for transmission I2C2TRN = (uint8_t)(*memAddr >> 8);
I2C2TRN = (uint8_t)(*memAddr & 0x00FF); while (I2C2STATbits.TRSTAT); // wait for transmission
while (I2C2STATbits.TRSTAT); // wait for transmission I2C2TRN = (uint8_t)(*memAddr & 0x00FF);
} while (I2C2STATbits.TRSTAT); // wait for transmission
if(send != NULL) { // guard against NULL pointer }
// Now send the actual data // Now send the actual data
for (loopVar = size; loopVar > 0; loopVar--) { // do until size hits zero if(send != NULL) {
I2C2TRN = *send; // load buffer with (next) data I2C2TRN = *send; // load buffer with data
while (I2C2STATbits.TRSTAT); // wait for transmission while (I2C2STATbits.TRSTAT); // wait for transmission
if (I2C2STATbits.ACKSTAT == 0) { if (I2C2STATbits.ACKSTAT == 0) {
// acknowledge received // acknowledge received
} else {
status |= 2; // NACK on data
}
send++; // good old pointer increment... hope it works!
}
} else { } else {
status |= NULL_ERROR; status |= DATA_NACK; // NACK on data
} }
I2C2CONbits.PEN = 1; // send STOP }
while (I2C2CONbits.PEN); // wait for stop to complete if(recv != NULL) { // guard against NULL pointers
// RECEIVE SECTION
I2C2CONbits.RSEN = 1; // send restart
while (I2C2CONbits.RSEN); // wait for restart
fullAddress = (addr << 1) | 0x01; // address is now for reading
I2C2TRN = fullAddress; // send address
while (I2C2STATbits.TRSTAT); // wait for transmission
if (I2C2STATbits.ACKSTAT == 0) {
// acknowledge received
} else {
status |= ADDR_NACK; // NACK on address
}
I2C2CONbits.RCEN = 1; // enable receiever
while (!I2C2STATbits.RBF); // wait for 8 bits to be receieved
*recv = I2C2RCV;
I2C2CONbits.ACKDT = 1; // change to NACK
I2C2CONbits.ACKEN = 1; // send ACKDT
while (I2C2CONbits.ACKEN); // wait for NACK to send
} else {
status |= NULL_ERROR;
}
break; I2C2CONbits.PEN = 1; // send STOP
case SINGLE_RECV: // Single receive while (I2C2CONbits.PEN); // wait for stop to complete
if(memAddr != NULL || send != NULL) { break;
fullAddress = addr << 1; // we are writing, thus R/W = 0 case MULTIPLE_RECV: // Multiple receive
while (I2C2STATbits.TRSTAT); // wait for any transmission to finish if(memAddr != NULL || send != NULL) { // only send the write address if needed
I2C2CONbits.SEN = 1; // send a start fullAddress = addr << 1; // we are writing, thus R/W = 0
while (I2C2CONbits.SEN); // wait for start to complete while (I2C2STATbits.TRSTAT); // wait for any transmission to finish
I2C2TRN = fullAddress; // send address I2C2CONbits.SEN = 1; // send a start
while (I2C2STATbits.TRSTAT); // wait for transmission while (I2C2CONbits.SEN); // wait for start to complete
if (I2C2STATbits.ACKSTAT == 0) { I2C2TRN = fullAddress; // send address
// acknowledge received while (I2C2STATbits.TRSTAT); // wait for transmission
} else { if (I2C2STATbits.ACKSTAT == 0) {
status |= 1; // NACK on address // acknowledge received
} } else {
} status |= 1; // NACK on address
if(memAddr != NULL) {
// Send memory address
I2C2TRN = (uint8_t)(*memAddr >> 8);
while (I2C2STATbits.TRSTAT); // wait for transmission
I2C2TRN = (uint8_t)(*memAddr & 0x00FF);
while (I2C2STATbits.TRSTAT); // wait for transmission
} }
}
if(memAddr != NULL) {
// Send memory address
I2C2TRN = (uint8_t)(*memAddr >> 8);
while (I2C2STATbits.TRSTAT); // wait for transmission
I2C2TRN = (uint8_t)(*memAddr & 0x00FF);
while (I2C2STATbits.TRSTAT); // wait for transmission
}
if(send != NULL) {
// Now send the actual data // Now send the actual data
if(send != NULL) { I2C2TRN = *send; // load buffer with data
I2C2TRN = *send; // load buffer with data while (I2C2STATbits.TRSTAT); // wait for transmission
while (I2C2STATbits.TRSTAT); // wait for transmission if (I2C2STATbits.ACKSTAT == 0) {
if (I2C2STATbits.ACKSTAT == 0) { // acknowledge received
// acknowledge received } else {
} else { status |= 2; // NACK on data
status |= DATA_NACK; // NACK on data
}
} }
if(recv != NULL) { // guard against NULL pointers }
// RECEIVE SECTION if(recv != NULL) {
I2C2CONbits.RSEN = 1; // send restart // RECEIVE SECTION
while (I2C2CONbits.RSEN); // wait for restart I2C2CONbits.RSEN = 1; // send restart
fullAddress = (addr << 1) | 0x01; // address is now for reading while (I2C2CONbits.RSEN); // wait for restart
I2C2TRN = fullAddress; // send address fullAddress = (addr << 1) | 0x01; // address is now for reading
while (I2C2STATbits.TRSTAT); // wait for transmission I2C2TRN = fullAddress; // send address
if (I2C2STATbits.ACKSTAT == 0) { while (I2C2STATbits.TRSTAT); // wait for transmission
// acknowledge received if (I2C2STATbits.ACKSTAT == 0) {
} else { // acknowledge received
status |= ADDR_NACK; // NACK on address } else {
} status |= 1; // NACK on address
}
for (loopVar = size; loopVar > 0; loopVar--) {
I2C2CONbits.RCEN = 1; // enable receiever I2C2CONbits.RCEN = 1; // enable receiever
while (!I2C2STATbits.RBF); // wait for 8 bits to be receieved while (!I2C2STATbits.RBF); // wait for 8 bits to be receieved
*recv = I2C2RCV; *recv = I2C2RCV;
I2C2CONbits.ACKDT = 1; // change to NACK recv++;
I2C2CONbits.ACKEN = 1; // send ACKDT if (loopVar > 1) {
while (I2C2CONbits.ACKEN); // wait for NACK to send I2C2CONbits.ACKDT = 0; // ACK
} else { I2C2CONbits.ACKEN = 1;
status |= NULL_ERROR; while (I2C2CONbits.ACKEN); // wait for ACK
}
I2C2CONbits.PEN = 1; // send STOP
while (I2C2CONbits.PEN); // wait for stop to complete
break;
case MULTIPLE_RECV: // Multiple receive
if(memAddr != NULL || send != NULL) { // only send the write address if needed
fullAddress = addr << 1; // we are writing, thus R/W = 0
while (I2C2STATbits.TRSTAT); // wait for any transmission to finish
I2C2CONbits.SEN = 1; // send a start
while (I2C2CONbits.SEN); // wait for start to complete
I2C2TRN = fullAddress; // send address
while (I2C2STATbits.TRSTAT); // wait for transmission
if (I2C2STATbits.ACKSTAT == 0) {
// acknowledge received
} else { } else {
status |= 1; // NACK on address I2C2CONbits.ACKDT = 1; // change to NACK
I2C2CONbits.ACKEN = 1; // send ACKDT
while (I2C2CONbits.ACKEN); // wait for NACK to send
} }
} }
if(memAddr != NULL) { } else {
// Send memory address status |= NULL_ERROR;
I2C2TRN = (uint8_t)(*memAddr >> 8); }
while (I2C2STATbits.TRSTAT); // wait for transmission I2C2CONbits.PEN = 1; // send STOP
I2C2TRN = (uint8_t)(*memAddr & 0x00FF); while (I2C2CONbits.PEN); // wait for stop to complete
while (I2C2STATbits.TRSTAT); // wait for transmission break;
case TEST_MODE: // infinite test mode
do {
for (int i = 0; i < max; ++i) {
uint8_t c = (int) (i * prime) % max;
I2C2CONbits.SEN = 1;
while (I2C2CONbits.SEN);
I2C2TRN = c;
while (I2C2STATbits.TBF); // wait for transmission
I2C2CONbits.PEN = 1;
while (I2C2CONbits.PEN);
} }
if(send != NULL) { } while (size--);
// Now send the actual data break;
I2C2TRN = *send; // load buffer with data default:
while (I2C2STATbits.TRSTAT); // wait for transmission status |= 0x04;
if (I2C2STATbits.ACKSTAT == 0) { break;
// acknowledge received
} else {
status |= 2; // NACK on data
}
}
if(recv != NULL) {
// RECEIVE SECTION
I2C2CONbits.RSEN = 1; // send restart
while (I2C2CONbits.RSEN); // wait for restart
fullAddress = (addr << 1) | 0x01; // address is now for reading
I2C2TRN = fullAddress; // send address
while (I2C2STATbits.TRSTAT); // wait for transmission
if (I2C2STATbits.ACKSTAT == 0) {
// acknowledge received
} else {
status |= 1; // NACK on address
}
for (loopVar = size; loopVar > 0; loopVar--) {
I2C2CONbits.RCEN = 1; // enable receiever
while (!I2C2STATbits.RBF); // wait for 8 bits to be receieved
*recv = I2C2RCV;
recv++;
if (loopVar > 1) {
I2C2CONbits.ACKDT = 0; // ACK
I2C2CONbits.ACKEN = 1;
while (I2C2CONbits.ACKEN); // wait for ACK
} else {
I2C2CONbits.ACKDT = 1; // change to NACK
I2C2CONbits.ACKEN = 1; // send ACKDT
while (I2C2CONbits.ACKEN); // wait for NACK to send
}
}
} else {
status |= NULL_ERROR;
}
I2C2CONbits.PEN = 1; // send STOP
while (I2C2CONbits.PEN); // wait for stop to complete
break;
case TEST_MODE: // infinite test mode
do {
for (int i = 0; i < max; ++i) {
uint8_t c = (int) (i * prime) % max;
I2C2CONbits.SEN = 1;
while (I2C2CONbits.SEN);
I2C2TRN = c;
while (I2C2STATbits.TBF); // wait for transmission
I2C2CONbits.PEN = 1;
while (I2C2CONbits.PEN);
}
} while (size--);
break;
default:
status |= 0x04;
break;
} }
return status; return status;
} }

View File

@ -3,7 +3,7 @@
* Author: Alexander Rowsell * Author: Alexander Rowsell
* *
* Created on May 3, 2015, 1:06 AM * Created on May 3, 2015, 1:06 AM
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
@ -31,7 +31,7 @@ enum statusCodes {
/** /**
* @class i2c * @class i2c
* @brief The i2c class, controls all i2c comms * @brief The i2c class, controls all i2c comms
* *
* This class is an abstraction of the I2C peripheral * This class is an abstraction of the I2C peripheral
* inside the PIC32MX1xx/2xx family of devices. * inside the PIC32MX1xx/2xx family of devices.
* Simply create an instance of this class, and then * Simply create an instance of this class, and then
@ -39,7 +39,7 @@ enum statusCodes {
* data over the I2C bus. Colours are excellent * data over the I2C bus. Colours are excellent
*/ */
class i2c { class i2c {
public: public:
i2c(uint32_t speed, uint32_t pclk); i2c(uint32_t speed, uint32_t pclk);
uint8_t transact(uint8_t addr, uint8_t *send, \ uint8_t transact(uint8_t addr, uint8_t *send, \

266
main.cpp
View File

@ -13,7 +13,7 @@
#include <sys/attribs.h> #include <sys/attribs.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "i2c.h" #include "i2c.hpp"
#include "FIFO.hpp" #include "FIFO.hpp"
#include "FlashStorage.hpp" #include "FlashStorage.hpp"
#include "UART.hpp" #include "UART.hpp"
@ -34,167 +34,169 @@ volatile uint8_t currentClip = 0;
#define AUDIO_SIZE 509176 #define AUDIO_SIZE 509176
const uint32_t audioSize[16] = {0x0000ba8d, 0x0000d063, 0x000069fa, 0x00007c3e, const uint32_t audioSize[16] = {0x0000ba8d, 0x0000d063, 0x000069fa, 0x00007c3e,
0x000030b4, 0x0000c676, 0x000020fd, 0x00005314, 0x00002db8, 0x00002fbd, 0x000030b4, 0x0000c676, 0x000020fd, 0x00005314, 0x00002db8, 0x00002fbd,
0x000046c0, 0x0000bc92, 0x0000a257, 0x00002830, 0x00011790, 0x0000a5b7}; 0x000046c0, 0x0000bc92, 0x0000a257, 0x00002830, 0x00011790, 0x0000a5b7
};
const uint32_t audioAddress[16] = {0x00, 0x0000ba8d, 0x00018af0, 0x0001f4ea, const uint32_t audioAddress[16] = {0x00, 0x0000ba8d, 0x00018af0, 0x0001f4ea,
0x00027128, 0x0002a1dc, 0x00036852, 0x0003894f, 0x0003dc63, 0x00040a1b, 0x00027128, 0x0002a1dc, 0x00036852, 0x0003894f, 0x0003dc63, 0x00040a1b,
0x000439d8, 0x00048098, 0x00053d2a, 0x0005df81, 0x000607b1, 0x00071f41}; 0x000439d8, 0x00048098, 0x00053d2a, 0x0005df81, 0x000607b1, 0x00071f41
};
#define dacAddress 0x62 #define dacAddress 0x62
void _delay(uint32_t cycles) { void _delay(uint32_t cycles) {
cycles += (uint32_t) ((double) cycles * 1.4); cycles += (uint32_t) ((double) cycles * 1.4);
while (cycles--); while (cycles--);
return; return;
} }
uint8_t initSystem(void) { uint8_t initSystem(void) {
/* set up GPIO */ /* set up GPIO */
SYSKEY = 0x0; SYSKEY = 0x0;
SYSKEY = 0xAA996655; SYSKEY = 0xAA996655;
SYSKEY = 0x556699AA; SYSKEY = 0x556699AA;
CFGCON &= ~(1 << 13); // unlock PPS CFGCON &= ~(1 << 13); // unlock PPS
// Pin configs // Pin configs
/* SPI: /* SPI:
* SO = RB5 * SO = RB5
* SI = RC8 * SI = RC8
* CS = RA4 * CS = RA4
* *
* I2C: * I2C:
* SDA: RB2 * SDA: RB2
* SCL: RB3 * SCL: RB3
* *
* UART: * UART:
* TX = RC5 * TX = RC5
* RX = RC3 * RX = RC3
*/ */
SDI1R = 0b0110; // RC8 SDI1R = 0b0110; // RC8
U1RXR = 0b0111; // RC3 U1RXR = 0b0111; // RC3
RPC0R = 0b0101; // OC1 on LED RPC0R = 0b0101; // OC1 on LED
RPB5R = 0b0011; // SD01 RPB5R = 0b0011; // SD01
RPC5R = 0b0001; // U1TX RPC5R = 0b0001; // U1TX
OSCCONCLR = 0x00000010; // idle mode OSCCONCLR = 0x00000010; // idle mode
SYSKEY = 0x12345678; // lock SYSKEY SYSKEY = 0x12345678; // lock SYSKEY
// set up button & LED // set up button & LED
ANSELACLR = 0xFFFF; ANSELACLR = 0xFFFF;
ANSELBCLR = 0xFFFF; ANSELBCLR = 0xFFFF;
ANSELCCLR = 0xFFFF; // clear all analog functions ANSELCCLR = 0xFFFF; // clear all analog functions
TRISCSET = 0x20; // PC5 is button input TRISCSET = 0x20; // PC5 is button input
TRISCCLR = 0x01; // PC0 is LED TRISCCLR = 0x01; // PC0 is LED
PORTCCLR = 0x01; // turn LED off at boot PORTCCLR = 0x01; // turn LED off at boot
CNENCSET = 0x20; // enable on PC5 CNENCSET = 0x20; // enable on PC5
CNPUCSET = 0x20; // pullup enable CNPUCSET = 0x20; // pullup enable
CNCONCSET = 0x8000; CNCONCSET = 0x8000;
IFS1CLR = 0x8000; IFS1CLR = 0x8000;
IPC8SET = 0xC0000; // priority 3 IPC8SET = 0xC0000; // priority 3
//IEC1SET = 0x8000; // enable pin change interrupt port C //IEC1SET = 0x8000; // enable pin change interrupt port C
/* Set up SPI1 */ /* Set up SPI1 */
TRISACLR = 0x10; TRISACLR = 0x10;
PORTASET = 0x10; PORTASET = 0x10;
TRISBCLR = 0x4000; // RB14 is SCK1 TRISBCLR = 0x4000; // RB14 is SCK1
SPI1BRG = 1; // 2.5MHz SPI1BRG = 1; // 2.5MHz
SPI1CONbits.ENHBUF = 0; // enable enhanced buffer SPI1CONbits.ENHBUF = 0; // enable enhanced buffer
SPI1CONbits.MSTEN = 1; // master mode SPI1CONbits.MSTEN = 1; // master mode
SPI1STATCLR = (1 << 6); // clear SPIROV SPI1STATCLR = (1 << 6); // clear SPIROV
SPI1CONbits.ON = 1; // enable SPI SPI1CONbits.ON = 1; // enable SPI
// set up timer (needs to be about 8kHz) // set up timer (needs to be about 8kHz)
T2CON = 0x0000; // timer continues in idle mode T2CON = 0x0000; // timer continues in idle mode
PR2 = 0x04E2; // 1250 = 10e6/8e3 PR2 = 0x04E2; // 1250 = 10e6/8e3
TMR2 = 0x0000; TMR2 = 0x0000;
IPC2bits.T2IP = 7; // priority 7 IPC2bits.T2IP = 7; // priority 7
IFS0bits.T2IF = 0; IFS0bits.T2IF = 0;
IEC0bits.T2IE = 1; // enable timer interrupt IEC0bits.T2IE = 1; // enable timer interrupt
INTCONSET = _INTCON_MVEC_MASK; INTCONSET = _INTCON_MVEC_MASK;
return 0; return 0;
} }
void updateDAC(i2c *bus, uint16_t data) { void updateDAC(i2c *bus, uint16_t data) {
uint8_t bytes[2] = {0x00, 0x00}; uint8_t bytes[2] = {0x00, 0x00};
bytes[0] = (uint8_t) (data >> 8) & 0x0F; // clear top half of top byte bytes[0] = (uint8_t) (data >> 8) & 0x0F; // clear top half of top byte
bytes[1] = (uint8_t) (data & 0x00FF); bytes[1] = (uint8_t) (data & 0x00FF);
bus->transact(dacAddress, bytes, NULL, 2, MULTIPLE_SEND); bus->transact(dacAddress, bytes, NULL, 2, MULTIPLE_SEND);
} }
int main(void) { int main(void) {
volatile uint16_t audioSampleShifted = 0; volatile uint16_t audioSampleShifted = 0;
volatile uint8_t audioSample = 0; volatile uint8_t audioSample = 0;
initSystem(); initSystem();
FIFO audioBuffer(64); FIFO audioBuffer(64);
UART serial(19200, 10e6); UART serial(19200, 10e6);
FlashStorage flash(&audioBuffer, &serial); FlashStorage flash(&audioBuffer, &serial);
i2c i2cBus(400e3, 10e6); i2c i2cBus(400e3, 10e6);
// this needs to be as early as possible, but after SPI and UART setup // this needs to be as early as possible, but after SPI and UART setup
// if(LATC & 0x20) { // if(LATC & 0x20) {
// // if button is held down at boot, it's programming mode // // if button is held down at boot, it's programming mode
// globalState = STATE_PROGRAMMING; // globalState = STATE_PROGRAMMING;
// flash.program(); // flash.program();
// } // }
const char testString[20] = "Welcome to Canada\n\r"; const char testString[20] = "Welcome to Canada\n\r";
// main state machine loop // main state machine loop
//flash.program(); //flash.program();
globalState == STATE_PLAYING; globalState == STATE_PLAYING;
while (1) { while (1) {
__builtin_disable_interrupts(); __builtin_disable_interrupts();
if (globalState == STATE_PLAYING) { if (globalState == STATE_PLAYING) {
if (audioBuffer.usedSize < 16) { if (audioBuffer.usedSize < 16) {
// read 48 bytes into buffer // read 48 bytes into buffer
flash.read(audioAddress[currentClip] + readByteCount, 48); flash.read(audioAddress[currentClip] + readByteCount, 48);
readByteCount += 48; readByteCount += 48;
} }
audioSample = audioBuffer.read(); audioSample = audioBuffer.read();
byteCount++; byteCount++;
if (byteCount >= audioSize[currentClip]) { if (byteCount >= audioSize[currentClip]) {
byteCount = 0; byteCount = 0;
readByteCount = 0; readByteCount = 0;
//globalState = STATE_IDLE; //globalState = STATE_IDLE;
} }
// Load sample into DAC // Load sample into DAC
audioSampleShifted = (uint16_t) (audioSample << 4); audioSampleShifted = (uint16_t) (audioSample << 4);
//updateDAC(&i2cBus, audioSampleShifted); //updateDAC(&i2cBus, audioSampleShifted);
serial.send(audioSample); serial.send(audioSample);
__builtin_enable_interrupts(); __builtin_enable_interrupts();
T2CONbits.ON = 1; // enable timer T2CONbits.ON = 1; // enable timer
asm volatile("wait"); asm volatile("wait");
} else if (globalState == STATE_IDLE) { } else if (globalState == STATE_IDLE) {
for (uint8_t i = 0; i < 20; i++) { for (uint8_t i = 0; i < 20; i++) {
serial.send(testString[i]); serial.send(testString[i]);
} }
__builtin_enable_interrupts(); __builtin_enable_interrupts();
T2CONbits.ON = 1; // enable timer T2CONbits.ON = 1; // enable timer
asm volatile("wait"); asm volatile("wait");
} }
} }
} }
extern "C" { extern "C" {
void __ISR(_TIMER_2_VECTOR, IPL7AUTO) Timer2Handler(void) { void __ISR(_TIMER_2_VECTOR, IPL7AUTO) Timer2Handler(void) {
T2CONbits.ON = 0; T2CONbits.ON = 0;
IFS0bits.T2IF = 0; IFS0bits.T2IF = 0;
} }
void __ISR(_CHANGE_NOTICE_VECTOR, IPL3AUTO) PinChangeHandler(void) { void __ISR(_CHANGE_NOTICE_VECTOR, IPL3AUTO) PinChangeHandler(void) {
// button is pushed // button is pushed
if (globalState == STATE_PLAYING) { if (globalState == STATE_PLAYING) {
return; // do nothing, we're already playing return; // do nothing, we're already playing
} }
// pick a random number // pick a random number
currentClip += 1; currentClip += 1;
currentClip = currentClip % 8; // roll back around currentClip = currentClip % 8; // roll back around
globalState = STATE_PLAYING; globalState = STATE_PLAYING;
IFS0CLR = 0x00000100; IFS0CLR = 0x00000100;
} }
} // end extern C } // end extern C