Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bsp/boards/openmote-b/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void board_init(void) {
uart_init();
radio_init();
i2c_init();
sensors_init();
//sensors_init();
cryptoengine_init();
}

Expand Down
18 changes: 9 additions & 9 deletions bsp/boards/openmote-b/sensors.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "board.h"
#include "sensors.h"

#include "si70x.h"
//#include "si70x.h"

//=========================== defines =========================================

Expand All @@ -25,7 +25,7 @@ sensors_vars_t sensors_vars;
/**
\brief Initialize sensors on the board
*/
void sensors_init(void) {
/*void sensors_init(void) {

memset(&sensors_vars,0,sizeof(sensors_vars_t));

Expand All @@ -38,23 +38,23 @@ void sensors_init(void) {
adc_sensor_init();
sensors_vars.sensorsTypes[SENSOR_ADCTEMPERATURE] = 1;

}
}*/

/**
\brief Returns a bool value indicating if a given sensor is present
\param[in] sensorType sensor type polled.
\param[out] returnVal presence of the sensor.
*/
bool sensors_is_present(uint8_t sensorType) {
/*bool sensors_is_present(uint8_t sensorType) {
return sensors_vars.sensorsTypes[sensorType];
}
}*/

/**
\brief Returns the callback for reading data from a given sensor
\param[in] sensorType sensor type used to associate the callback.
\param[out] callback for reading data.
*/
callbackRead_cbt sensors_getCallbackRead(uint8_t sensorType) {
/*callbackRead_cbt sensors_getCallbackRead(uint8_t sensorType) {

switch (sensorType) {
case SENSOR_TEMPERATURE:
Expand All @@ -67,14 +67,14 @@ callbackRead_cbt sensors_getCallbackRead(uint8_t sensorType) {
return NULL;
}

}
}*/

/**
\brief Returns the callback for converting data from a given sensor
\param[in] sensorType sensor type used to associate the callback.
\param[out] callback for converting data.
*/
callbackConvert_cbt sensors_getCallbackConvert(uint8_t sensorType) {
/*callbackConvert_cbt sensors_getCallbackConvert(uint8_t sensorType) {

switch (sensorType) {
case SENSOR_TEMPERATURE:
Expand All @@ -87,6 +87,6 @@ callbackConvert_cbt sensors_getCallbackConvert(uint8_t sensorType) {
return NULL;
}

}
}*/

//=========================== private =========================================
230 changes: 230 additions & 0 deletions projects/openmote-b/00std_spi/00std_spi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
/**
\brief definition of the "spi" bsp module.
\author Xavier Vilajosana <xvilajosana@eecs.berkeley.edu>, September 2017.
*/
#include "board.h"
#include "board_info.h"
#include "ssi.h"
#include "spi.h"
#include "gpio.h"
#include "ioc.h"
#include "sys_ctrl.h"

#include <headers/hw_ints.h>
#include <headers/hw_ioc.h>
#include <headers/hw_memmap.h>
#include <headers/hw_ssi.h>
#include <headers/hw_sys_ctrl.h>
#include <headers/hw_types.h>


//=========================== defines =========================================
#define SPI_PIN_SSI_CLK GPIO_PIN_0 // CLK
#define SPI_PIN_SSI_FSS GPIO_PIN_1 // CSn
#define SPI_PIN_SSI_RX GPIO_PIN_2 // MISO
#define SPI_PIN_SSI_TX GPIO_PIN_3 // MOSI
#define SPI_GPIO_SSI_BASE GPIO_B_BASE

//=========================== variables =======================================

typedef struct {
// information about the current transaction
uint8_t* pNextTxByte;
uint16_t numTxedBytes;
uint16_t txBytesLeft;
spi_return_t returnType;
uint8_t* pNextRxByte;
uint16_t maxRxBytes;
spi_first_t isFirst;
spi_last_t isLast;
// state of the module
uint8_t busy;
#ifdef SPI_IN_INTERRUPT_MODE
// callback when module done
spi_cbt callback;
#endif
} spi_vars_t;

spi_vars_t spi_vars;

//*********Variables to use as parameters of spi_txrx function****************//

static char stringToPrint[]="MessageToTest\r\n";
size_t len=sizeof(stringToPrint);

//=========================== prototypes ======================================
static void disableInterrupts(void);
static void enableInterrupts(void);
//=========================== public ==========================================

void spi_init(){
// clear variables
memset(&spi_vars,0,sizeof(spi_vars_t));

//Set the CLK , MOSI(TX) and MISO(RX) pins as Hardware-controlled (Configures GPIO_AFSEL-->1)
GPIOPinTypeSSI(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_CLK );
GPIOPinTypeSSI(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_RX );
GPIOPinTypeSSI(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_TX );

//Set the SS pin as Software-controlled outputs (configures GPIO_AFSEL-->0 (software) and GPIO_DIR-->1 (Output) )
//Only FSS can be used as SOFTWARE controlled OUTPUT
GPIOPinTypeGPIOOutput(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_FSS);

//Set SS to High (writes into GPIO_DATA register)
GPIOPinWrite(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_FSS, SPI_PIN_SSI_FSS);

/*//Set pins to low
GPIOPinWrite(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_TX, 0);
GPIOPinWrite(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_CLK, 0);*/

//Configuration of SSI1 peripheral
SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_SSI1);
SysCtrlPeripheralSleepEnable(SYS_CTRL_PERIPH_SSI1);
SysCtrlPeripheralDeepSleepDisable(SYS_CTRL_PERIPH_SSI1);

//Disabling SSI (writes into SSI_CR1 --> 0)
SSIDisable(SSI1_BASE);

//Set clock source (The baud clock source for the SSI to select.)
SSIClockSourceSet(SSI1_BASE, SSI_CLOCK_PIOSC); //The precision internal oscillator

/*Configure output signal to IOC_Pxx_SEL register
Each signal is identified with its address table 9.1 in T.I datasheet*/
IOCPinConfigPeriphOutput(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_CLK, IOC_MUX_OUT_SEL_SSI1_CLKOUT);
IOCPinConfigPeriphOutput(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_TX, IOC_MUX_OUT_SEL_SSI1_TXD);
IOCPinConfigPeriphOutput(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_FSS, IOC_MUX_OUT_SEL_SSI1_FSSOUT);
//Configures hardware peripheral input selection (i.e. IOC_SSIRXD_SSI1)
IOCPinConfigPeriphInput(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_RX, IOC_SSIRXD_SSI1);


//Sets SSI_CR0 (SPI MODE and Data Size), SSI_CR1(Protocol), SSI_CPSR(Clock prescaler divisor)
//According to the LoRaSX1276 datasheet, the corresponding mode is CPOL=0 , CPHA=0 which is FRF mode 0
SSIConfigSetExpClk(SSI1_BASE, SysCtrlIOClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, SysCtrlIOClockGet()/2/*16000000*/, 8);

//Enable the SSI1 module(writes into CR1)
SSIEnable(SSI1_BASE);

//Call the spi_txrx function
spi_txrx((uint8_t*)stringToPrint,len,SPI_FIRSTBYTE,(uint8_t*)16,16,SPI_FIRST,SPI_NOTLAST);
}

#ifdef SPI_IN_INTERRUPT_MODE
void spi_setCb(spi_cbt cb) {
spi_vars.spi_cb = cb;
}
#endif

void spi_txrx(uint8_t* bufTx,
uint16_t lenbufTx,
spi_return_t returnType,
uint8_t* bufRx,
uint16_t maxLenBufRx,
spi_first_t isFirst,
spi_last_t isLast) {

uint32_t data,i;
GPIOPinWrite(GPIO_C_BASE, GPIO_PIN_3, GPIO_PIN_3);
// register spi frame to send
spi_vars.pNextTxByte = bufTx;
spi_vars.numTxedBytes = 0;
spi_vars.txBytesLeft = lenbufTx;
spi_vars.returnType = returnType;
spi_vars.pNextRxByte = bufRx;
spi_vars.maxRxBytes = maxLenBufRx;
spi_vars.isFirst = isFirst;
spi_vars.isLast = isLast;

// SPI is now busy
spi_vars.busy = 1;

// lower CS signal to have slave listening (FSS is managed through software, not hardware)
if (spi_vars.isFirst==SPI_FIRST) {
GPIOPinWrite(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_FSS, 0);
}

for ( i = 0; i < lenbufTx; i++)
{
// Push a byte
SSIDataPut(SSI1_BASE, spi_vars.pNextTxByte[i]);

// Wait until it is complete
while(SSIBusy(SSI1_BASE));

// Read a byte
SSIDataGet(SSI1_BASE, &data);

// Store the result
spi_vars.pNextRxByte[i] = (uint8_t)(data & 0xFF);
// one byte less to go
}

if (spi_vars.isLast==SPI_LAST) {
GPIOPinWrite(SPI_GPIO_SSI_BASE, SPI_PIN_SSI_FSS, SPI_PIN_SSI_FSS);
}

// SPI is not busy anymore
spi_vars.busy = 0;
GPIOPinWrite(GPIO_C_BASE, GPIO_PIN_3, 0);
}

//=========================== private =========================================

port_INLINE void enableInterrupts(void)
{
// Enable the SPI interrupt
SSIIntEnable(SSI1_BASE, (SSI_TXFF | SSI_RXFF | SSI_RXTO | SSI_RXOR));

// Enable the SPI interrupt
IntEnable(INT_SSI1);
}

port_INLINE void disableInterrupts(void)
{
// Disable the SPI interrupt
SSIIntDisable(SSI1_BASE, (SSI_TXFF | SSI_RXFF | SSI_RXTO | SSI_RXOR));

// Disable the SPI interrupt
IntDisable(INT_SSI1);
}

//=========================== interrupt handlers ==============================

kick_scheduler_t spi_isr() {
#ifdef SPI_IN_INTERRUPT_MODE
uint32_t data;
// save the byte just received in the RX buffer
status = SSIIntStatus(SSI1_BASE, true);

// Clear SPI interrupt in the NVIC
IntPendClear(INT_SSI1);

SSIDataGet(SSI1_BASE, &data);

// Store the result
spi_vars.pNextRxByte = (uint8_t)(data & 0xFF);

// one byte less to go
spi_vars.pNextTxByte++;
spi_vars.pNextRxByte++;
spi_vars.txBytesLeft--;

if (spi_vars.txBytesLeft>0) {
// write next byte to TX buffer
SSIDataPut(SSI1_BASE, *spi_vars.pNextTxByte);

} else {
// SPI is not busy anymore
spi_vars.busy = 0;

// SPI is done!
if (spi_vars.callback!=NULL) {
// call the callback
spi_vars.spi_cb();
// kick the OS
return KICK_SCHEDULER;
}
}

#endif
return DO_NOT_KICK_SCHEDULER;
}
Loading