"Spi.H": Spi1 - Init Spi1 - TX Spi1 - Txbuffer
"Spi.H": Spi1 - Init Spi1 - TX Spi1 - Txbuffer
Module
SPI
Revision
1.0
Description
* This module establishes a timer and polls the OPAMP and TVS services to
* transmit ship + aiming data to the Display PIC through SPI1.
*
Author:
* Ethan Kurteff 5-20-21
Revised:
* Ethan Kurteff 5-21-21 | Swapped position of HULL and SHIELD in TxArray
******************************************************************************/
// This module
#include "SPI.h"
// Hardware
#include <xc.h>
#include <proc/p32mx170f256b.h>
#include <sys/attribs.h> // for ISR macros
/*SPI Parameters*/
#define SPI_BIT_RATE 2E6
#define SPI_BIT_WIDTH 8
#define SPI_UPDATE_TIME 50//Time in mS between SPI transmissions to Disp. PIC
#define MESSAGE_LENGTH 16 //How long will our SPI Tx packet be in bytes?
/****************************************************************************
Function
InitSPItx
****************************************************************************/
bool InitSPItx(uint8_t Priority)
{
ES_Event_t ThisEvent;
MyPriority = Priority;
/****************************************************************************
Function
PostSPItx
****************************************************************************/
bool PostSPItx(ES_Event_t ThisEvent)
{
return ES_PostToService(MyPriority, ThisEvent);
}
/****************************************************************************
Function
RunSPItx
****************************************************************************/
ES_Event_t RunSPItx(ES_Event_t ThisEvent)
{
ES_Event_t ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors
switch (ThisEvent.EventType)
{
case ES_INIT:
{
ES_Timer_InitTimer(SPI_TIMER, SPI_UPDATE_TIME);//Start SPI timer
}
break;
case ES_TIMEOUT:
{
switch (ThisEvent.EventParam)
{
case SPI_TIMER:
{
//Grab graph values from OPAMP service
powerLevels thisPL= getPowerLevels();
uint8_t shieldLevel = getShieldLevel();
uint8_t hullLevel = getHullLevel();
//
// uint16_t XCoord;
// uint16_t YCoord;
//Construct TxArray
TxArray[0] = 0xFF; //Start delimiter MSB
TxArray[1] = 0xFE; //Start delimiter LSB
TxArray[2] = thisJL.X >> 8; //Joy X MSB
TxArray[3] = thisJL.X; //Joy X LSB
TxArray[4] = thisJL.Y >> 8; //Joy Y MSB
TxArray[5] = thisJL.Y; //Joy Y LSB
TxArray[6] = weaponsRange; //Weapons Range
TxArray[7] = hullLevel; //Hull capacity
TxArray[8] = shieldLevel; //Shield capacity
TxArray[9] = weaponsCapacity; //Weapons capacity
TxArray[10] = thisPL.navigation; //Navigation Power
TxArray[11] = ourShipPos.XCoord >> 8;//Ship X MSB
TxArray[12] = ourShipPos.XCoord; //Ship X LSB
TxArray[13] = ourShipPos.YCoord >> 8;//Ship Y MSB
TxArray[14] = ourShipPos.YCoord; //Ship Y LSB
if(QueryZener() != ZenerDead){ //If our ship is alive:
TxArray[15] = 1; //Set alive bit
}
else{ //Else ship is dead:
TxArray[15] = 0; //Clear alive bit
}
}break;
}
}
break;
}
return ReturnEvent;
}
/****************************************************************************
Function
SPI_Init
Parameters
bitRate, bitWidth
Returns
void
Description
set up the SPI system for use. Set the clock phase and polarity, master mode
clock source, baud rate, SS control, transfer width (8-bits)
Notes
Author: Ethan Kurteff 5/20/21
****************************************************************************/
void SPI1_Init(uint32_t bitRate, uint8_t bitWidth){
/*Calculate baud rate divisor to get our desired clock rate or below.
* Assumes PB clock (FPB) is 20MHz
*FSCK = FPB/(2*(BRG+1) = 20E6/(2*(999+1))*/
/* IF PBCLK is evenly divisible by desired freq*/
if(PBCLK%(2*bitRate)==0) SPI1BRG = PBCLK/(2*bitRate)-1;//Calculate BRG exactly
else SPI1BRG = PBCLK/(2*bitRate);//Step the speed down one notch
/*TURN IT ON!*/
SPI1CONbits.ON = 1;//Turn on SPI1
/****************************************************************************
Function
SPI1_Tx
Parameters
uint8_t data the 8-bit value to be sent out through the SPI
Returns
void
Description
write the data to the SPIxBUF and then wait for it to go out (SPITBF)
Notes
don't forget to read the buffer after the transfer to prevent over-runs
****************************************************************************/
void SPI1_Tx(uint8_t data){
while(SPI1STATbits.SPITBF);//Wait while tx buffer is full
SPI1BUF = data;//Write data to SPI xmit buffer
while(!SPI1STATbits.SRMT);//Wait until shift register is empty
SPI1BUF;//Read buffer to clear/prevent over-runs
}
/****************************************************************************
Function
SPI1_TxBuffer
Parameters
uint8_t *buffer, a pointer to the buffer to be transmitted
uint8_t length the number of bytes in the buffer to transmit
Returns
void
Description
loop through buffer calling SPI_Tx for each element in the buffer
Notes
****************************************************************************/
void SPI1_TxBuffer(uint8_t *buffer, uint8_t length){
uint8_t index = 0;//Determines our position in buffer
while(index < length)//While we are in bounds of buffer array
{
SPI1_Tx(*(buffer+index));//Transmit the index(th) element of buffer
index++;//Move on to next element
}
}