Other Parts Discussed in Thread: ADS1292
Tool/software: TI C/C++ Compiler
when I removed the red color comments, pin Board_SPI1_CSN is alway low, and spi is broken.
if I dont't do that, SPI is ok, Board_SPI1_CSN level is OK. It's really strange.
#define Board_SPI1_MISO IOID_6 /*ADS1292 DOUT*/
#define Board_SPI1_MOSI IOID_5 /*ADS1292 DIN */
#define Board_SPI1_CLK IOID_4 /*ADS1292 CLK */
#define Board_SPI1_CSN IOID_7 /*ADS1292 CSN */
/*
* @brief StartSpiEmgTrans
*
* @param 无
*
* @return
*/
bool StartSpiEmgTrans(uint32_t ui32Base, SPI_TRANS *pTransaction){
pSpiEmgTrans = pTransaction;
pSpiEmgTrans->status = SPI_TRANS_STARTED;
//HWREGB(GPIO_BASE+GPIO_O_DOUT3_0 + Board_SPI1_CSN) = 1; // 拉低片选
HWREGB(GPIO_BASE+GPIO_O_DOUT3_0 + Board_SPI1_CSN) = 0; // 拉低片选
//uint32_t currVal;
//currVal = PIN_getOutputValue(Board_SPI1_CSN);
//PIN_setOutputValue(CsPinHandle, Board_SPI1_CSN, 0);
//PINCC26XX_setOutputValue(Board_SPI1_CSN, 0);
SSIIntEnable(ui32Base, SSI_TXFF|SSI_RXFF|SSI_RXTO|SSI_RXOR);
return true;
}
/*
* @brief SPI1_IRQHandler
*
* @param 无
*
* @return SPI1 中断处理函数
*/
void SPI1_IRQHandler(void){
static uint32_t uLen, uRcvCnt;
uint32_t intStatus, uiSpiData = 0, i;
intStatus = SSIIntStatus(SSI1_BASE, true);
while(SSIStatus(SSI1_BASE) & SSI_RX_NOT_EMPTY){
//SSIDataGet(SSI1_BASE, &uiSpiData);
uiSpiData = HWREG(SSI1_BASE + SSI_O_DR);
*(pSpiEmgTrans->rxBuf + uRcvCnt) = (uiSpiData & 0xFF);
if(++uRcvCnt >= pSpiEmgTrans->count) uRcvCnt = 0;
}
if(intStatus & SSI_RXTO){
//SSIIntClear(SSI1_BASE, SSI_RXTO);
HWREG(SSI1_BASE + SSI_O_ICR) |= SSI_RXTO;
}
if(intStatus & SSI_RXOR){ // RX overrun
//SSIIntClear(SSI1_BASE, SSI_RXOR);
HWREG(SSI1_BASE + SSI_O_ICR) |= SSI_RXOR;
SSIDisable(SSI1_BASE);
}
//uint32_t currVal;
if(intStatus & SSI_TXFF){ // Transmit FIFO not full
//HWREGB(GPIO_BASE+GPIO_O_DOUT3_0 + Board_SPI1_CSN) = 0; // 拉低片选
SSIDataPut(SSI1_BASE, *(pSpiEmgTrans->txBuf));
++pSpiEmgTrans->txBuf;
if(++uLen >= pSpiEmgTrans->count){
uLen = 0;
while(SSIBusy(SSI1_BASE)); // 等待数据传输完成
for(i = 0; i < 25; ++i){ // 延迟6个us 满足ads1292时序要求
SSIIntDisable(SSI1_BASE, SSI_TXFF);
}
pSpiEmgTrans->status = SPI_TRANS_COMPLETED;
HWREGB(GPIO_BASE+GPIO_O_DOUT3_0 + Board_SPI1_CSN) = 1; // 拉低片选
//currVal = PIN_getOutputValue(Board_SPI1_CSN);
//PIN_setOutputValue(CsPinHandle, Board_SPI1_CSN, !currVal);
}
}
//uint32_t currVal;
//if(pSpiEmgTrans->status == SPI_TRANS_COMPLETED){
// currVal = PIN_getOutputValue(Board_SPI1_CSN);
// PIN_setOutputValue(CsPinHandle, Board_SPI1_CSN, !currVal);
//PINCC26XX_setOutputValue(Board_SPI1_CSN, 1);
//}
}
/*
* SpiDriver.c
*
* Created on: 2017��3��19��
* Author: User
*/
#include <inc/hw_ioc.h>
#include <inc/hw_gpio.h>
#include <inc/hw_ssi.h>
#include <driverlib/prcm.h>
#include <driverlib/ssi.h>
#include <ti/drivers/SPI.h>
//#include <ti/drivers/PIN/PINCC26XX.h>
#include <ti/sysbios/family/arm/cc26xx/Power.h>
#include <ti/sysbios/family/arm/cc26xx/PowerCC2650.h>
#include "Board.h"
#include "SpiDriver.h"
#define TX_FIFO_LENGTH 16 //SPI TX FIFO Buffer Length
#define RX_FIFO_LENGTH 16 //SPI RX FIFO Buffer Length
extern void SPI0_IRQHandler(void);
extern void SPI1_IRQHandler(void);
static SPI_TRANS *pSpiEmgTrans;
static SPI_TRANS *pSpiStm32Trans;
/* Pin driver handles */
static PIN_Handle CsPinHandle;
/* Global memory storage for a PIN_Config table */
static PIN_State CsPinState;
/*
* Initial spi1 chip select pin configuration table
*/
static PIN_Config CsPinTable[] = {
Board_SPI1_CSN | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH |IOC_STD_OUTPUT,
Board_SPI0_CSN | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH |IOC_STD_OUTPUT,
PIN_TERMINATE
};
/*
* @brief Spi Initialize
*
* @param ui32Base SPI Register base address
*
* @return None.
*/
void SpiInit(uint32_t ui32Base){
if(ui32Base == SSI0_BASE){
/**************************************��Դ��ʱ������************************************/
Power_setDependency(PERIPH_SSI0); //SSI0��Դ��
PRCMPeripheralRunEnable(PRCM_PERIPH_SSI0); //ʹ��SSI0ʱ��
PRCMPeripheralSleepEnable(PRCM_PERIPH_SSI0);
PRCMPeripheralDeepSleepEnable(PRCM_PERIPH_SSI0);
//Power_setDependency(PRCM_PERIPH_GPIO); //GPIO��Դ��
//PRCMPeripheralRunEnable(PRCM_PERIPH_GPIO); //ʹ��GPIOʱ��
//PRCMPeripheralSleepEnable(PRCM_PERIPH_GPIO);
//PRCMPeripheralDeepSleepEnable(PRCM_PERIPH_GPIO);
PRCMLoadSet(); //����ʱ������
/***************************************�� �� �� ��**************************************/
IOCPortConfigureSet(Board_SPI0_MOSI, IOC_PORT_MCU_SSI0_RX, IOC_STD_INPUT);
IOCPortConfigureSet(Board_SPI0_MISO, IOC_PORT_MCU_SSI0_TX, IOC_STD_OUTPUT);
IOCPortConfigureSet(Board_SPI0_CLK, IOC_PORT_MCU_SSI0_CLK, IOC_STD_OUTPUT);
//IOCPortConfigureSet(Board_SPI0_CSN, IOC_PORT_GPIO, IOC_STD_OUTPUT);
//IOCPortConfigureSet(Board_SPI0_CSN, IOC_PORT_MCU_SSI0_FSS, IOC_STD_OUTPUT);
/*************************************SSI�Ĵ�������************************************/
HWREG(ui32Base + SSI_O_CR1) = 0; //MASTER Motorola SPI_POL1_PHA1 SPI 1000000bps
//HWREG(ui32Base + SSI_O_CR1) |= SSI_CR1_MS_MASTER|SSI_CR1_LBM;
HWREG(ui32Base + SSI_O_CR1) |= SSI_CR1_MS_MASTER;
HWREG(ui32Base + SSI_O_CPSR) = 2;
HWREG(ui32Base + SSI_O_CR0) = (0x18 << 8) | SSI_CR0_SPO_HIGH | SSI_CR0_SPH_2ND_CLK_EDGE | SSI_CR0_FRF_MOTOROLA_SPI | SSI_CR0_DSS_8_BIT;
HWREG(ui32Base + SSI_O_CR1) |= SSI_CR1_SSE_SSI_ENABLED; //ʹ��SPI
SSIIntRegister(ui32Base, SPI0_IRQHandler); //�жϴ������
//SSIIntEnable(ui32Base, SSI_TXFF|SSI_RXFF|SSI_RXTO); //ʹ���ж�
//SSIIntEnable(ui32Base, SSI_TXFF|SSI_RXFF|SSI_RXTO|SSI_RXOR); //ʹ���ж�
}
if(ui32Base == SSI1_BASE){
/**************************************��Դ��ʱ������************************************/
Power_setDependency(PERIPH_SSI1); //SSI1��Դ��
PRCMPeripheralRunEnable(PRCM_PERIPH_SSI1); //ʹ��SSI1ʱ��
PRCMPeripheralSleepEnable(PRCM_PERIPH_SSI1);
PRCMPeripheralDeepSleepEnable(PRCM_PERIPH_SSI1);
//Power_setDependency(PRCM_PERIPH_GPIO); //GPIO��Դ��
//PRCMPeripheralRunEnable(PRCM_PERIPH_GPIO); //ʹ��GPIOʱ��
//PRCMPeripheralSleepEnable(PRCM_PERIPH_GPIO);
//PRCMPeripheralDeepSleepEnable(PRCM_PERIPH_GPIO);
PRCMLoadSet(); //����ʱ������
/***************************************�� �� �� ��**************************************/
IOCPortConfigureSet(Board_SPI1_MISO, IOC_PORT_MCU_SSI1_RX, IOC_STD_INPUT);
IOCPortConfigureSet(Board_SPI1_MOSI, IOC_PORT_MCU_SSI1_TX, IOC_STD_OUTPUT);
IOCPortConfigureSet(Board_SPI1_CLK, IOC_PORT_MCU_SSI1_CLK, IOC_STD_OUTPUT);
//IOCPortConfigureSet(Board_SPI1_CSN, IOC_PORT_GPIO, IOC_STD_OUTPUT);
//IOCPortConfigureSet(Board_SPI1_CSN, IOC_PORT_MCU_SSI1_FSS, IOC_STD_OUTPUT);
/*************************************SSI�Ĵ�������************************************/
HWREG(ui32Base + SSI_O_CR1) = 0; //MASTER Motorola SPI_POL0_PHA1 SPI 1000000bps
//HWREG(ui32Base + SSI_O_CR1) |= SSI_CR1_MS_MASTER|SSI_CR1_LBM;
HWREG(ui32Base + SSI_O_CR1) |= SSI_CR1_MS_MASTER;
HWREG(ui32Base + SSI_O_CPSR) = 2;
HWREG(ui32Base + SSI_O_CR0) = (0x18 << 8) | SSI_CR0_SPO_LOW | SSI_CR0_SPH_2ND_CLK_EDGE | SSI_CR0_FRF_MOTOROLA_SPI | SSI_CR0_DSS_8_BIT;
HWREG(ui32Base + SSI_O_CR1) |= SSI_CR1_SSE_SSI_ENABLED; //ʹ��SPI
SSIIntRegister(ui32Base, SPI1_IRQHandler);
//SSIIntEnable(ui32Base, SSI_TXFF|SSI_RXFF|SSI_RXTO); //ʹ���ж�
//SSIIntEnable(ui32Base, SSI_TXFF|SSI_RXFF|SSI_RXTO|SSI_RXOR); //ʹ���ж�
}
CsPinHandle = PIN_open(&CsPinState, CsPinTable);
}
/*
* @brief StartSpiEmgTrans
*
* @param ��
*
* @return
*/
bool StartSpiEmgTrans(uint32_t ui32Base, SPI_TRANS *pTransaction){
pSpiEmgTrans = pTransaction;
pSpiEmgTrans->status = SPI_TRANS_STARTED;
//HWREGB(GPIO_BASE+GPIO_O_DOUT3_0 + Board_SPI1_CSN) = 1; // ����Ƭѡ
HWREGB(GPIO_BASE+GPIO_O_DOUT3_0 + Board_SPI1_CSN) = 0; // ����Ƭѡ
//uint32_t currVal;
//currVal = PIN_getOutputValue(Board_SPI1_CSN);
//PIN_setOutputValue(CsPinHandle, Board_SPI1_CSN, 0);
//PINCC26XX_setOutputValue(Board_SPI1_CSN, 0);
SSIIntEnable(ui32Base, SSI_TXFF|SSI_RXFF|SSI_RXTO|SSI_RXOR);
return true;
}
/*
* @brief ClrSpiStm32Cs
*
* @param ��
*
* @return
*/
void ClrSpiStm32Cs(void){
HWREGB(GPIO_BASE+GPIO_O_DOUT3_0 + Board_SPI0_CSN) = 0; // ����Ƭѡ
}
/*
* @brief SetSpiStm32Cs
*
* @param ��
*
* @return
*/
void SetSpiStm32Cs(void){
HWREGB(GPIO_BASE+GPIO_O_DOUT3_0 + Board_SPI0_CSN) = 1; // ����Ƭѡ
}
/*
* @brief StartSpiStm32Trans
*
* @param ��
*
* @return
*/
bool StartSpiStm32Trans(uint32_t ui32Base, SPI_TRANS *pTransaction){
pSpiStm32Trans = pTransaction;
pSpiStm32Trans->status = SPI_TRANS_STARTED;
HWREGB(GPIO_BASE+GPIO_O_DOUT3_0 + Board_SPI0_CSN) = 0; // ����Ƭѡ
SSIIntEnable(ui32Base, SSI_TXFF|SSI_RXFF|SSI_RXTO|SSI_RXOR);
return true;
}
/*
* @brief SPI0_IRQHandler
*
* @param ��
*
* @return SPI0 �жϴ������
*/
void SPI0_IRQHandler(void){
static uint32_t uLen, uRcvCnt;
uint32_t intStatus, uiSpiData;
intStatus = SSIIntStatus(SSI0_BASE, true);
while(SSIStatus(SSI0_BASE) & SSI_RX_NOT_EMPTY){
//SSIDataGet(SSI0_BASE, &uiSpiData);
uiSpiData = HWREG(SSI0_BASE + SSI_O_DR);
*(pSpiStm32Trans->rxBuf + uRcvCnt) = (uiSpiData & 0xFF);
if(++uRcvCnt >= pSpiStm32Trans->count) uRcvCnt = 0;
}
if(intStatus & SSI_RXTO){
//SSIIntClear(SSI0_BASE, SSI_RXTO);
HWREG(SSI0_BASE + SSI_O_ICR) |= SSI_RXTO;
}
if(intStatus & SSI_RXOR){ // RX overrun
//SSIIntClear(SSI0_BASE, SSI_RXOR);
HWREG(SSI0_BASE + SSI_O_ICR) |= SSI_RXOR;
SSIDisable(SSI0_BASE);
}
if(intStatus & SSI_TXFF){ // Transmit FIFO not full
//HWREGB(GPIO_BASE+GPIO_O_DOUT3_0 + Board_SPI0_CSN) = 0; // ����Ƭѡ
SSIDataPut(SSI0_BASE, *(pSpiStm32Trans->txBuf));
++pSpiStm32Trans->txBuf;
if(++uLen >= pSpiStm32Trans->count){
uLen = 0;
while(SSIBusy(SSI0_BASE)); // �ȴ����ݴ������
SSIIntDisable(SSI0_BASE, SSI_TXFF);
pSpiStm32Trans->status = SPI_TRANS_COMPLETED;
}
}
uint32_t currVal;
if(pSpiStm32Trans->status == SPI_TRANS_COMPLETED){
currVal = PIN_getOutputValue(Board_SPI0_CSN);
PIN_setOutputValue(CsPinHandle, Board_SPI0_CSN, !currVal);
}
}
/*
* @brief SPI1_IRQHandler
*
* @param ��
*
* @return SPI1 �жϴ������
*/
void SPI1_IRQHandler(void){
static uint32_t uLen, uRcvCnt;
uint32_t intStatus, uiSpiData = 0, i;
intStatus = SSIIntStatus(SSI1_BASE, true);
while(SSIStatus(SSI1_BASE) & SSI_RX_NOT_EMPTY){
//SSIDataGet(SSI1_BASE, &uiSpiData);
uiSpiData = HWREG(SSI1_BASE + SSI_O_DR);
*(pSpiEmgTrans->rxBuf + uRcvCnt) = (uiSpiData & 0xFF);
if(++uRcvCnt >= pSpiEmgTrans->count) uRcvCnt = 0;
}
if(intStatus & SSI_RXTO){
//SSIIntClear(SSI1_BASE, SSI_RXTO);
HWREG(SSI1_BASE + SSI_O_ICR) |= SSI_RXTO;
}
if(intStatus & SSI_RXOR){ // RX overrun
//SSIIntClear(SSI1_BASE, SSI_RXOR);
HWREG(SSI1_BASE + SSI_O_ICR) |= SSI_RXOR;
SSIDisable(SSI1_BASE);
}
//uint32_t currVal;
if(intStatus & SSI_TXFF){ // Transmit FIFO not full
//HWREGB(GPIO_BASE+GPIO_O_DOUT3_0 + Board_SPI1_CSN) = 0; // ����Ƭѡ
SSIDataPut(SSI1_BASE, *(pSpiEmgTrans->txBuf));
++pSpiEmgTrans->txBuf;
if(++uLen >= pSpiEmgTrans->count){
uLen = 0;
while(SSIBusy(SSI1_BASE)); // �ȴ����ݴ������
for(i = 0; i < 25; ++i){ // �ӳ�6��us ����ads1292ʱ��Ҫ��
SSIIntDisable(SSI1_BASE, SSI_TXFF);
}
pSpiEmgTrans->status = SPI_TRANS_COMPLETED;
HWREGB(GPIO_BASE+GPIO_O_DOUT3_0 + Board_SPI1_CSN) = 1; // ����Ƭѡ
//currVal = PIN_getOutputValue(Board_SPI1_CSN);
//PIN_setOutputValue(CsPinHandle, Board_SPI1_CSN, !currVal);
}
}
//uint32_t currVal;
//if(pSpiEmgTrans->status == SPI_TRANS_COMPLETED){
// currVal = PIN_getOutputValue(Board_SPI1_CSN);
// PIN_setOutputValue(CsPinHandle, Board_SPI1_CSN, !currVal);
//PINCC26XX_setOutputValue(Board_SPI1_CSN, 1);
//}
}
/*
* @brief SPI����һ���ֽ�
*
* @param Data �������ֽ�����
*
* @return DR�Ĵ�����ֵ
*/
static uint8_t Spi0_SendByte(uint8_t Data)
{
uint32_t uRcvData;
// Loop while Tx buffer is not emplty
while(!(SSIStatus(SSI0_BASE) & SSI_TX_NOT_FULL));
// Send byte through the SPI0 peripheral
SSIDataPut(SSI0_BASE, Data);
// Wait to receive a byte
while(!(SSIStatus(SSI0_BASE) & SSI_RX_NOT_EMPTY));
// read the byte from the SPI bus
SSIDataGet(SSI0_BASE, &uRcvData);
return uRcvData;
}
/*
* @brief SPI�����ַ���
*
* @param pSend �������ֽڴ�������ʼָ��
* Length �������ַ������ݳ���
* @return ��
*/
void Spi0_SendStr(uint8_t *pSend, uint8_t Length)
{
//ClrSpiStm32Cs();
while(Length--){
Spi0_SendByte(*pSend++);
}
//SetSpiStm32Cs();
}
/*
* @brief SPI��ȡ�ַ���
*
* @param pSend �������ֽڴ�������ʼָ��
* Length �������ַ������ݳ���
* pRcvStr �������ַ���������ʼָ��*
* @return ��
*/
void Spi0_RcvStr(uint8_t *pSend, uint8_t Length, uint8_t *pRcvStr)
{
//ClrSpiStm32Cs();
while(Length--){
*pRcvStr++ = Spi0_SendByte(*pSend++);
}
//SetSpiStm32Cs();
}