您好,
我在运行SPI设备时遇到问题。 它是KX134-1211 Rev. 1.0 加速传感器套件。
我已按如下方式连接设备:
味增- DIO8
MOSI - DIO9.
CLK - DIO10
CS - DIO11.
我正在将空项目用于实验目的。
首先,我将传感器套件初始化为16位阻止模式。 在这里,我可以设置传感器套件的引脚,以在给定频率触发。
正如我在示波器上看到的那样,这很好。
传感器套件的触发器引脚与Launchpad的DIO14 (BTN2)相连。
BTN-2在触发时具有回调函数,该函数启动SPI并发送请求。
此函数处于回调模式。 在我的理解中,这意味着每次使用SPI_TRANSFORT()时,它都会触发给定的Callbackfunction。 但它不是
所以我在锁定模式下尝试了它。 直到循环中的第12次调用,此操作一直运行正常。
我不知道应用程序何时跳进错误函数,但它总是在与SPI相关的呼叫中。
在我尝试运行时,我也尝试了SPICC26xxDMA.h中的手动模式,但它不起作用。
我还阅读了一些关于SPI-functions are not be called in a thread, because of the used hwi_disable, btriggert callback function of "BTN14"是HWI。 是吗?
我的syscfg如下所示:
按钮:2 BTNS ->按钮向右和按钮向左。 两个"使用硬件"都是对应的LaunchPad按钮BTN-X
GPIO:4 (2 BTN,2个LED)->按钮1和按钮2 (与上面相同)-名称"Config_GPIO _BTNX"-回调函数:空(在代码中设置)。
中断优先级:7-最低
感谢你的帮助。
TLDR:SPI函数不会触发callbackfunction (为什么?) -阻止模式中的SPI跳转到错误函数-如何使SPI运行?
* ======== empty.c ========
*/
/* For usleep() */
#include <unistd.h>
#include <stdint.h>
#include <stddef.h>
/* Driver Header files */
#include <ti/drivers/GPIO.h>
// #include <ti/drivers/I2C.h>
#include <ti/drivers/SPI.h>
#include <SPICC26X2DMA.h>
#include <spiKX134.h>
// #include <ti/drivers/UART.h>
// #include <ti/drivers/Watchdog.h>
/* Driver configuration */
#include "ti_drivers_config.h"
// defines
//SPI
uint16_t accelData[10][6];
uint16_t SPI_watermark = 0; //Anzahl der Datensätze im AccelData array
uint8_t spiFrameNbr = 1; // Anzahl der zu übertragenden Frames
SPI_Handle spi;
SPI_Params spiParams;
SPI_Transaction spiTransaction;
uint64_t coapData;
static uint16_t SPI_full = 10;
uint16_t transmitBuffer[6]; //Init des transmitBuffer arrays
uint16_t receiveBuffer[6]; //Init des receiveBuffer arrays
volatile bool transferOK;
//Platz für Funktionen..
void spiRun();
static void spi_done_callback();
static void coap_handle_button_press();
void spi_start_request();
void spi_stop_request();
static void btn_interrupt_handler() //uint8_t index
{
spi_start_request();
coap_handle_button_press();
//spi_stop_request();
// if(index == CONFIG_GPIO_BTN1) { }
// else if(index == CONFIG_GPIO_BTN2) { }
}
//SPI Hilfsfunktionen
void spiWritePrep(volatile uint16_t* transmitBuffer) { //erstes BIT 0 für schreiben auf SPI
*transmitBuffer = *transmitBuffer << 8;
*transmitBuffer = *transmitBuffer & 0b0111111111111111;
}
void spiWritePrep16bit(volatile uint16_t* transmitBuffer1, volatile uint16_t* transmitBuffer2) { //erstes BIT 0 für schreiben auf SPI
*transmitBuffer1 = *transmitBuffer1 | *transmitBuffer2;
}
void spiReadPrep(volatile uint16_t* transmitBuffer) { //erstes BIT 1 für lesen auf SPI
*transmitBuffer = *transmitBuffer | 0b1000000000000000;
}
//SPI Hauptfunktion
void spiRun(){
SPI_init(); // Initialize the SPI driver
SPI_Params_init(&spiParams); // Initialize SPI parameters. Änderungen bestimmter Parameter möglich, siehe nächste Zeile
//manche Werte sind die Default-Werte, können bei Bedarf umgestellt werden. Infos in SPI.h
spiParams.transferMode = SPI_MODE_BLOCKING; //Blocking / Callback
spiParams.transferTimeout = SPI_WAIT_FOREVER; //Time in system ticks
spiParams.transferCallbackFxn = NULL; //Funktion nach Übertragung
spiParams.mode = SPI_MASTER; //Master/Slave mode
spiParams.bitRate = 1000000; //1Mhz
spiParams.dataSize = 16; // 8-bit data size
spiParams.frameFormat = SPI_POL1_PHA1; //!< SPI mode Polarity 1 Phase 1
spi = SPI_open(CONFIG_SPI_0, &spiParams); // SPI_open("nummer des SPI wie in sysconf.", spiParams)
if (spi == NULL) {
while (1); // SPI_open() failed
}
// Fill in transmitBuffer 1
// Set acc to stand-by mode
spiTransaction.count = spiFrameNbr;
spiTransaction.txBuf = (void *)transmitBuffer;
spiTransaction.rxBuf = (void *)receiveBuffer;
transmitBuffer[0] = CNTL1;
spiWritePrep(&transmitBuffer[0]);
transmitBuffer[1] = 0x00; //Value
spiWritePrep16bit(&transmitBuffer[0], &transmitBuffer[1]);
transferOK = SPI_transfer(spi, &spiTransaction);
if (!transferOK) {
// Error in SPI or transfer already in progress.
while (1);
}
// Fill in transmitBuffer 2
// Interrupt Control1(INC1) enables physical interrupt pin5 INT1 (active high)
transmitBuffer[0] = INC1;
spiWritePrep(&transmitBuffer[0]);
transmitBuffer[1] = 0x30; //Value
spiWritePrep16bit(&transmitBuffer[0], &transmitBuffer[1]);
transferOK = SPI_transfer(spi, &spiTransaction);
if (!transferOK) {
// Error in SPI or transfer already in progress.
while (1);
}
// Fill in transmitBuffer 3
// set the Data Ready interrupt to be reported
transmitBuffer[0] =INC4;
spiWritePrep(&transmitBuffer[0]);
transmitBuffer[1] =0x10; //Value
spiWritePrep16bit(&transmitBuffer[0], &transmitBuffer[1]);
transferOK = SPI_transfer(spi, &spiTransaction);
if (!transferOK) {
// Error in SPI or transfer already in progress.
while (1);
}
// Fill in transmitBuffer 4
// set trigger-rate Infos in spiKX134.h
transmitBuffer[0] =ODCNTL;
spiWritePrep(&transmitBuffer[0]);
transmitBuffer[1] = ODR10 | IIR_OFF | LPRO_OFF | FSTUP_OFF; //Value
spiWritePrep16bit(&transmitBuffer[0], &transmitBuffer[1]);
transferOK = SPI_transfer(spi, &spiTransaction);
if (!transferOK) {
// Error in SPI or transfer already in progress.
while (1);
}
// Fill in transmitBuffer 5
// set acc to operating mode
transmitBuffer[0] =CNTL1;
spiWritePrep(&transmitBuffer[0]);
transmitBuffer[1] =0xE0; //Value
spiWritePrep16bit(&transmitBuffer[0], &transmitBuffer[1]);
transferOK = SPI_transfer(spi, &spiTransaction);
if (!transferOK) {
// Error in SPI or transfer already in progress.
while (1);
}
SPI_close(spi);
}
void spi_start_request(){
SPI_init(); // Initialize the SPI driver
SPI_Params_init(&spiParams); // Initialize SPI parameters. Änderungen bestimmter Parameter möglich, siehe nächste Zeile
//manche Werte sind die Default-Werte, können bei Bedarf umgestellt werden. Infos in SPI.h
spiParams.transferMode = SPI_MODE_CALLBACK; //Blocking / Callback
spiParams.transferTimeout = SPI_WAIT_FOREVER; //Time in system ticks
spiParams.transferCallbackFxn = spi_done_callback; // spi_done_callback; //Funktion nach Übertragung
spiParams.mode = SPI_MASTER; //Master/Slave mode
spiParams.bitRate = 1000000; //1Mhz
spiParams.dataSize = 16; // 8-bit data size
spiParams.frameFormat = SPI_POL1_PHA1; //!< SPI mode Polarity 1 Phase 1
spi = SPI_open(CONFIG_SPI_0, &spiParams); // SPI_open("nummer des SPI wie in sysconf.", spiParams)
if (spi == NULL) {
while (1); // SPI_open() failed
}
//SPI_control(spi, SPICC26X2DMA_CMD_CLR_MANUAL, NULL);
GPIO_write(CONFIG_GPIO_RLED, 1);
}
static void coap_handle_button_press() //fct for button/HWI
{
// SPI Request on buttonpress/HWI-trigger
spiTransaction.count = 6;
spiTransaction.txBuf = (void *)transmitBuffer;
spiTransaction.rxBuf = (void *)receiveBuffer;
//Push arguments to the first 8 bit
transmitBuffer[0] = XOUT_H << 8;
transmitBuffer[1] = XOUT_L << 8;
transmitBuffer[2] = YOUT_H << 8;
transmitBuffer[3] = YOUT_L << 8;
transmitBuffer[4] = ZOUT_H << 8;
transmitBuffer[5] = ZOUT_L << 8;
transferOK = SPI_transfer(spi, &spiTransaction);
if (!transferOK)
{
while(1);// Error in SPI or transfer already in progress.
}
// accelData[SPI_watermark][0] = receiveBuffer[0];
// accelData[SPI_watermark][1] = receiveBuffer[1];
// accelData[SPI_watermark][2] = receiveBuffer[2];
// accelData[SPI_watermark][3] = receiveBuffer[3];
// accelData[SPI_watermark][4] = receiveBuffer[4];
// accelData[SPI_watermark][5] = receiveBuffer[5];
//
// GPIO_write(CONFIG_GPIO_RLED, 0);
//eventOS_event_send(&event); gibt kein Event
}
static void spi_done_callback(SPI_Handle spi, SPI_Transaction *spiTransaction){
if (spiTransaction->status != SPI_TRANSFER_COMPLETED) {
transferOK = false;
SPI_transferCancel(spi);
spi_stop_request();
}
else {
transferOK = true;
accelData[SPI_watermark][0] = receiveBuffer[0];
accelData[SPI_watermark][1] = receiveBuffer[1];
accelData[SPI_watermark][2] = receiveBuffer[2];
accelData[SPI_watermark][3] = receiveBuffer[3];
accelData[SPI_watermark][4] = receiveBuffer[4];
accelData[SPI_watermark][5] = receiveBuffer[5];
spi_stop_request();
}
}
void spi_stop_request(){
if(SPI_watermark == SPI_full){
SPI_watermark = 0;
}
else{
SPI_watermark++;
}
GPIO_write(CONFIG_GPIO_RLED, 0);
SPI_close(spi);
spi = NULL;
}
/*
* ======== mainThread ========
*/
void *mainThread(void *arg0)
{
/* 1 second delay */
uint32_t time = 1;
/* Call driver init functions */
GPIO_init();
// I2C_init();
// UART_init();
// Watchdog_init();
/* Configure the LED pin */
GPIO_setConfig(CONFIG_GPIO_RLED, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
spiRun();
/* Setup callback for btn int */
GPIO_setCallback(CONFIG_GPIO_BTN1, btn_interrupt_handler);
GPIO_enableInt(CONFIG_GPIO_BTN1);
GPIO_setCallback(CONFIG_GPIO_BTN2, btn_interrupt_handler);
GPIO_enableInt(CONFIG_GPIO_BTN2);
while (1) {
sleep(time);
GPIO_toggle(CONFIG_GPIO_GLED);
}
}