Files
TX/source/spi.c
2025-06-11 10:55:00 -05:00

313 lines
8.2 KiB
C

/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "LPC54114_cm4.h"
#include "fsl_spi.h"
#include "pin_mux.h"
#include "board.h"
#include "fsl_debug_console.h"
#include <stdbool.h>
#include <stdint.h>
#include "spi.h"
#include "io.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define SPI3_MASTER SPI3
#define SPI3_MASTER_IRQ FLEXCOMM3_IRQn
#define SPI3_MASTER_CLK_SRC kCLOCK_Flexcomm3
#define SPI3_MASTER_CLK_FREQ CLOCK_GetFlexCommClkFreq(3)
#define LCD_SPI_SSEL 1
#define LCD_SPI_SPOL kSPI_Spol1ActiveHigh
#define RADIO_SPI_SSEL 2
//#define RADIO_SPI_SPOL kSPI_Spo2ActiveAllLow
//SPI0
#define SPI0_MASTER SPI0
#define SPI0_MASTER_IRQ FLEXCOMM0_IRQn
#define SPI0_MASTER_CLK_SRC kCLOCK_Flexcomm0
#define SPI0_MASTER_CLK_FREQ CLOCK_GetFlexCommClkFreq(3) //TODO: Which clock?
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
//SPI3
static uint8_t SPI3_txBuff[SPI_XFER_BUFFER_SIZE];
static uint8_t SPI3_rxBuff[SPI_XFER_BUFFER_SIZE];
spi_master_config_t SPI3_config = {0};
spi_transfer_t SPI3_xfer = {0};
//SPI0
static uint8_t SPI0_txBuff[SPI_XFER_BUFFER_SIZE];
static uint8_t SPI0_rxBuff[SPI_XFER_BUFFER_SIZE];
spi_master_config_t SPI0_config = {0};
spi_transfer_t SPI0_xfer = {0};
uint8_t Port_State[3]; // copy of Shift register I/O expander
/*******************************************************************************
* Code
******************************************************************************/
void SPI_Init(void)
{
// Set GP CS High
SPI0_Chip_Select(CS_HIGH,SDSIGNAL); // Set SD generator high as default.
SPI0_Chip_Select(CS_HIGH,SIGNAL); // Set SD generator high as default.
SPI0_Chip_Select(CS_HIGH,RAMP); //
SPI0_Chip_Select(CS_HIGH,AMPLITUDE); //
SPI0_Chip_Select(CS_HIGH,EXPANDER); //
SPI0_Chip_Select(CS_HIGH,E2PROM); //
SPI0_Chip_Select(CS_HIGH,PSU_VCTRL); //
// Initializes FC3 for LCD
uint32_t srcFreq = 0;
/*
* userConfig.enableLoopback = false;
* userConfig.enableMaster = true;
* userConfig.polarity = kSPI_ClockPolarityActiveHigh;
* userConfig.phase = kSPI_ClockPhaseFirstEdge;
* userConfig.direction = kSPI_MsbFirst;
*
*/
//SPI3: LCD and RADIO
SPI_MasterGetDefaultConfig(&SPI3_config);
srcFreq = SPI3_MASTER_CLK_FREQ;
SPI3_config.sselNum = (spi_ssel_t)LCD_SPI_SSEL;
SPI3_config.sselPol = (spi_spol_t)LCD_SPI_SPOL;
SPI3_config.baudRate_Bps = 500000U;
SPI_MasterInit(SPI3_MASTER, &SPI3_config, srcFreq);
//Link Radio
//SPI0: other shiat
SPI_MasterGetDefaultConfig(&SPI0_config);
srcFreq = SPI0_MASTER_CLK_FREQ;
SPI0_config.baudRate_Bps = 500000U;
SPI_MasterInit(SPI0_MASTER, &SPI0_config, srcFreq);
}
void SPI3_Test(void) //NOT USED ANYWHERE
{
/* Init Buffer*/
for (uint32_t i = 0; i < SPI_XFER_BUFFER_SIZE; i++)
{
SPI3_txBuff[i] = 0xAA;
}
while(1)
{
GPIO_PinWrite(GPIO, 0, 6, 1);
SPI3_SendBytes(SPI3_txBuff, 1);
GPIO_PinWrite(GPIO, 0, 6, 0);
uint32_t keithTWPia = 1000000;
while(keithTWPia--);
}
}
void SPI3_SendBytes(uint8_t *sendData, uint16_t numBytes)
{
uint8_t throwawayBuffer[numBytes];
//TODO: Setup userConfig to use LCD_SPI_SSEL and LCD_SPI_SPOL
/*Start Transfer*/
SPI3_xfer.txData = sendData;
SPI3_xfer.rxData = throwawayBuffer;
SPI3_xfer.dataSize = numBytes; //sizeof(rxBuff);
SPI3_xfer.configFlags = kSPI_FrameAssert;
SPI_MasterTransferBlocking(SPI3_MASTER, &SPI3_xfer);
}
void SPI0_SendBytes(uint8_t *sendData, uint16_t numBytes, SPI_MODE_t destination) //Extra arg
{
uint8_t throwawayBuffer[numBytes];
SPI0_SetupForDDS(1, destination); //Enter DDS mode if taking to a DDS
SPI0_Chip_Select(CS_LOW, destination);
/*Start Transfer*/
SPI0_xfer.txData = sendData;
SPI0_xfer.rxData = throwawayBuffer;
SPI0_xfer.dataSize = numBytes; //sizeof(rxBuff);
SPI0_xfer.configFlags = kSPI_FrameAssert;
#if 1 //troubleshooting
status_t status = SPI_MasterTransferBlocking(SPI0_MASTER, &SPI0_xfer);
if(status != kStatus_Success)
{
uint32_t foo = 0;
foo++; //Code never gets here even when EEPROM test fails.
}
#else
SPI_MasterTransferBlocking(SPI0_MASTER, &SPI0_xfer);
#endif
SPI0_Chip_Select(CS_HIGH, destination);
SPI0_SetupForDDS(0, destination); //Exit DDS mode if talking to a DDS
}
/*
* Setup SPI0 for talking to the DDS chips
* DDS chips require cpol = 1, normal state is cpol = 0
* @arg onOff 1 = enter DDS mode, 0 = exit DDS mode (return to default setup)
* @arg destination the device we are talking to. Use to determine if talking to a DDS
*/
void SPI0_SetupForDDS(uint32_t onOff, SPI_MODE_t destination)
{
if((destination == SIGNAL) || (destination == SDSIGNAL) || (destination == RAMP)) //if talking to a DDS
{
SPI_Deinit(SPI0_MASTER);
SPI_MasterGetDefaultConfig(&SPI0_config);
SPI0_config.baudRate_Bps = 500000U;
if(onOff) //Only change required for AD9838
{
SPI0_config.polarity = kSPI_ClockPolarityActiveLow; //activeLow = 1
}
else
{
SPI0_config.polarity = kSPI_ClockPolarityActiveHigh; //activeHigh = 0
}
SPI_MasterInit(SPI0_MASTER, &SPI0_config, SPI0_MASTER_CLK_FREQ);
}
}
/*void SPI0_SendBytes(uint8_t *sendData, uint16_t numBytes, SPI_MODE_t destination) //Extra arg
{
uint8_t throwawayBuffer[numBytes];
SPI0_Chip_Select(CS_LOW, destination);
/*Start Transfer
SPI0_xfer.txData = sendData;
SPI0_xfer.rxData = throwawayBuffer;
SPI0_xfer.dataSize = numBytes; //sizeof(rxBuff);
SPI0_xfer.configFlags = kSPI_FrameAssert;
#if 1 //troubleshooting
status_t status = SPI_MasterTransferBlocking(SPI0_MASTER, &SPI0_xfer);
if(status != kStatus_Success)
{
uint32_t foo = 0;
foo++; //Code never gets here even when EEPROM test fails.
}
#else
SPI_MasterTransferBlocking(SPI0_MASTER, &SPI0_xfer);
#endif
SPI0_Chip_Select(CS_HIGH, destination);
}
*/
/*
void SPI0_SendPotData(uint16_t *sendData, uint16_t numWords, SPI_MODE_t destination) //Extra arg
{
uint16_t throwawayBuffer[numWords];
// Reconfigure SPI to 10 bits
SPI0_config.dataWidth = kSPI_Data10Bits;
SPI_MasterInit(SPI0_MASTER, &SPI0_config, SPI3_MASTER_CLK_FREQ);
SPI0_Chip_Select(CS_LOW, destination);
//Start Transfer
SPI0_xfer.txData = sendData;
SPI0_xfer.rxData = throwawayBuffer;
SPI0_xfer.dataSize = numWords; //sizeof(rxBuff);
SPI0_xfer.configFlags = kSPI_FrameAssert;
SPI_MasterTransferBlocking(SPI0_MASTER, &SPI0_xfer);
SPI0_Chip_Select(CS_HIGH, destination);
// Return SPI to normal bit length.
SPI0_config.dataWidth = kSPI_Data8Bits;
SPI_MasterInit(SPI0_MASTER, &SPI0_config, SPI3_MASTER_CLK_FREQ);
}
*/
void SPI0_Chip_Select(uint8_t state, SPI_MODE_t destination)
{
switch(destination)
{
case SIGNAL:
GPIO_WRITE(PIN_SIG_CS, state);
break;
case SDSIGNAL:
GPIO_WRITE(PIN_SD_CS, state);
break;
case BOTH_SIGNAL:
GPIO_WRITE(PIN_SIG_CS, state);
GPIO_WRITE(PIN_SD_CS, state);
break;
case RAMP:
GPIO_WRITE(PIN_RAMP_CS, state);
break;
case AMPLITUDE:
GPIO_WRITE(PIN_POT_CS, state);
break;
case EXPANDER:
GPIO_WRITE(PIN_PORT_LE_CS, state);
break;
case E2PROM:
GPIO_WRITE(PIN_EEP_CS, state);
break;
case PSU_VCTRL:
GPIO_WRITE(PIN_POT_CS2, state);
break;
}
}