Skip to content
4 changes: 2 additions & 2 deletions src/bittybuzz/buzz_scripts/main.bzz
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
include "behaviors/follow_leader.bzz"
include "behaviors/blinky.bzz"

function init() {
exec = create_exec(100);
exec = create_exec(2000);
}

function step() {
Expand Down
6 changes: 6 additions & 0 deletions src/bsp/src/stm32/hal/include/hal/esp_spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ void EspSpi_WriteCS(bool state);
*/
bool EspSpi_ReadCS();

/**
* Read the USER0 pin
* @return Status of the pin
*/
bool EspSpi_ReadUser0();

/**
* @brief Callback used when reception has finished. Calls the user callback provided in
* espSpiTransmitDma()
Expand Down
2 changes: 2 additions & 0 deletions src/bsp/src/stm32/hal/src/esp_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ void EspSpi_WriteCS(bool state) {

bool EspSpi_ReadCS() { return HAL_GPIO_ReadPin(ESP_CS_GPIO_Port, ESP_CS_Pin) == GPIO_PIN_SET; }

bool EspSpi_ReadUser0() { return HAL_GPIO_ReadPin(ESP_USER0_Port, ESP_USER0_Pin) == GPIO_PIN_SET; }

void EspSpi_RxCallback() {
if (rxCpltCallbackFct != NULL && rxCallbackContext != NULL) {
rxCpltCallbackFct(rxCallbackContext);
Expand Down
7 changes: 3 additions & 4 deletions src/bsp/src/stm32/include/SpiEsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,13 @@ class SpiEsp : public ICommInterface {
ICRC& m_crc;
ILogger& m_logger;

enum class transmitState { IDLE, SENDING_HEADER, SENDING_PAYLOAD, ERROR } m_txState;
enum class transmitState { IDLE, SENDING_HEADER, SENDING_PAYLOAD } m_txState;
enum class receiveState {
IDLE,
RECEIVING_HEADER,
PARSING_HEADER,
RECEIVING_PAYLOAD,
VALIDATE_CRC,
ERROR
VALIDATE_CRC
} m_rxState;

struct message {
Expand All @@ -51,7 +50,7 @@ class SpiEsp : public ICommInterface {

std::array<uint8_t, 4 * ESP_SPI_MAX_MESSAGE_LENGTH> m_data;
CircularBuff m_circularBuf;
TaskHandle_t m_receivingTaskHandle, m_sendingTaskHandle = nullptr;
TaskHandle_t m_receivingTaskHandle, m_sendingTaskHandle, m_driverTaskHandle = nullptr;
EspHeader::Header m_outboundHeader;
EspHeader::Header* m_inboundHeader;

Expand Down
74 changes: 22 additions & 52 deletions src/bsp/src/stm32/src/SpiEsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
#include <cstring>

void task(void* context) {
constexpr uint16_t loopRate = 20;
// This is to give time for ESP to be ready for next transaction
constexpr uint16_t loopRate = 3;
while (true) {
static_cast<SpiEsp*>(context)->execute();
Task::delay(loopRate);
Expand Down Expand Up @@ -54,14 +55,13 @@ bool SpiEsp::send(const uint8_t* buffer, uint16_t length) {
m_txState = transmitState::SENDING_HEADER;
// Wait for transmission to be over. Will be notified when ACK received or upon error
m_sendingTaskHandle = xTaskGetCurrentTaskHandle();
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
if (m_txState == transmitState::ERROR) {
m_logger.log(LogLevel::Error, "Error occurred...");
return false;
m_hasSentPayload = false;
while (!m_hasSentPayload) {
ulTaskNotifyTake(pdTRUE, 20);
}
m_logger.log(LogLevel::Debug, "Payload sent!");
m_sendingTaskHandle = nullptr;
return m_crcOK;
return true;
}
bool SpiEsp::receive(uint8_t* buffer, uint16_t length) {
if (buffer == nullptr || length > ESP_SPI_MAX_MESSAGE_LENGTH) {
Expand All @@ -82,21 +82,20 @@ bool SpiEsp::isConnected() const { return m_isConnected; }

void SpiEsp::execute() {
uint32_t txLengthBytes = 0;
uint32_t rxLengthBytes = 0;
uint32_t rxLengthBytes = EspHeader::sizeBytes;
auto* txBuffer = (uint8_t*)&m_outboundHeader; // Send header by default;
if (m_driverTaskHandle == nullptr) {
m_driverTaskHandle = xTaskGetCurrentTaskHandle();
}

switch (m_rxState) {
case receiveState::IDLE:
if (!m_inboundRequest) {
m_inboundRequest = EspSpi_ReadCS();
}
m_inboundRequest = EspSpi_ReadUser0();
if (m_inboundRequest || m_txState != transmitState::IDLE) {
rxLengthBytes = EspHeader::sizeBytes;
m_rxState = receiveState::RECEIVING_HEADER;
}
break;
case receiveState::RECEIVING_HEADER:
rxLengthBytes = EspHeader::sizeBytes;
break;
case receiveState::PARSING_HEADER:
m_inboundHeader = (EspHeader::Header*)m_inboundMessage.m_data.data();
Expand All @@ -106,10 +105,8 @@ void SpiEsp::execute() {
m_logger.log(LogLevel::Debug, "Bytes were: | %d | %d | %d | %d |",
m_inboundMessage.m_data[0], m_inboundMessage.m_data[1],
m_inboundMessage.m_data[2], m_inboundMessage.m_data[3]);
m_rxState = receiveState::ERROR;
if (m_hasSentPayload) {
m_txState = transmitState::ERROR;
}
m_inboundMessage.m_sizeBytes = 0;
m_rxState = receiveState::RECEIVING_HEADER;
m_isConnected = false;
break;
}
Expand All @@ -135,17 +132,8 @@ void SpiEsp::execute() {
m_outboundHeader.systemState.stmSystemState.failedCrc = 0;
m_rxState = receiveState::RECEIVING_PAYLOAD;
} else {
rxLengthBytes = EspHeader::sizeBytes;
m_rxState = receiveState::RECEIVING_HEADER;
}
// Payload has been sent. Check crc and notify sending task
if (m_hasSentPayload) {
m_hasSentPayload = false;
m_crcOK = !m_inboundHeader->systemState.stmSystemState.failedCrc;
if (m_sendingTaskHandle != nullptr) {
xTaskNotifyGive(m_sendingTaskHandle);
}
}
break;
case receiveState::RECEIVING_PAYLOAD:
rxLengthBytes = m_inboundHeader->txSizeBytes;
Expand All @@ -172,17 +160,6 @@ void SpiEsp::execute() {
m_inboundMessage.m_payloadSize = 0;
m_inboundMessage.m_sizeBytes = 0;
m_rxState = receiveState::RECEIVING_HEADER;
rxLengthBytes = EspHeader::sizeBytes;
break;
case receiveState::ERROR:
rxLengthBytes = EspHeader::sizeBytes;
m_inboundMessage.m_sizeBytes = 0;
m_rxState = receiveState::RECEIVING_HEADER;
CircularBuff_clear(&m_circularBuf);
if (m_receivingTaskHandle != nullptr) {
xTaskNotifyGive(m_receivingTaskHandle);
}
m_logger.log(LogLevel::Debug, "Error within Spi driver ESP - RX");
break;
}
if (m_inboundRequest && m_txState == transmitState::IDLE) {
Expand All @@ -201,28 +178,19 @@ void SpiEsp::execute() {
case transmitState::SENDING_PAYLOAD:
txLengthBytes = m_outboundMessage.m_sizeBytes;
txBuffer = m_outboundMessage.m_data.data();
m_hasSentPayload = false;
m_crcOK = false;
break;
case transmitState::ERROR:
m_crcOK = false;
EspSpi_WriteCS(true);
if (m_sendingTaskHandle != nullptr) {
xTaskNotifyGive(m_sendingTaskHandle);
}
m_txState = transmitState::SENDING_HEADER;
m_logger.log(LogLevel::Debug, "Error within Spi driver ESP - TX");
break;
}

if ((m_inboundRequest || m_outboundMessage.m_sizeBytes != 0 ||
m_inboundMessage.m_sizeBytes != 0) &&
m_txState != transmitState::ERROR && m_rxState != receiveState::ERROR) {
if (m_inboundRequest || m_outboundMessage.m_sizeBytes != 0 ||
m_inboundMessage.m_sizeBytes != 0) {

EspSpi_WriteCS(false);
uint32_t finalSize = std::max(txLengthBytes, rxLengthBytes);
m_inboundMessage.m_data.fill(0);
EspSpi_TransmitReceiveDma(txBuffer, m_inboundMessage.m_data.data(), finalSize,
SpiEsp::espTxRxCallback, this);
ulTaskNotifyTake(pdTRUE, 20);
}
}

Expand All @@ -237,7 +205,7 @@ void SpiEsp::updateOutboundHeader() {
void SpiEsp::espInterruptCallback(void* context) {
auto* instance = static_cast<SpiEsp*>(context);
// Interrupt is on both falling edge and rising edge.
instance->m_inboundRequest = EspSpi_ReadCS();
instance->m_inboundRequest = EspSpi_ReadUser0();
}

void SpiEsp::espTxRxCallback(void* context) {
Expand All @@ -255,16 +223,18 @@ void SpiEsp::espTxRxCallback(void* context) {
// This should never be called. The state machine should never be in any other state during
// the ISR.
instance->m_logger.log(LogLevel::Error, "Interrupted called on invalid state");
instance->m_txState = transmitState::ERROR;
break;
}

BaseType_t yield;
if (instance->m_txState == transmitState::SENDING_PAYLOAD) {
instance->m_txState = transmitState::IDLE;
instance->m_outboundMessage.m_sizeBytes = 0;
instance->m_outboundMessage.m_payloadSize = 0;
instance->m_hasSentPayload = true;
vTaskNotifyGiveFromISR(instance->m_sendingTaskHandle, &yield);
}
vTaskNotifyGiveFromISR(instance->m_driverTaskHandle, &yield);
portYIELD_FROM_ISR(yield);
}

ConnectionType SpiEsp::getType() const { return ConnectionType::SPI; }
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <pheromones/IHiveMindHostDeserializer.h>
#include <pheromones/MessageDTO.h>

class MessageDispatcher : IMessageDispatcher {
class MessageDispatcher : public IMessageDispatcher {
public:
MessageDispatcher(ICircularQueue<MessageDTO>& buzzOutputQ,
ICircularQueue<MessageDTO>& hostOutputQ,
Expand Down
9 changes: 9 additions & 0 deletions src/message-handler/src/HiveMindHostApiRequestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ bool HiveMindHostApiRequestHandler::handleHiveMindHostApiRequest(
uint16_t requestId, const MessageDTO& message, const HiveMindHostApiRequestDTO& request) {

if (std::holds_alternative<BytesDTO>(request.getRequest())) {
if (m_bsp.getUUId() != message.getSourceId()) {
return m_remoteQueue.push(message);
}
return m_hostQueue.push(message);
}

Expand All @@ -48,6 +51,9 @@ bool HiveMindHostApiRequestHandler::handleHiveMindHostApiRequest(
HiveMindHostApiResponseDTO hmResp(neighborResp);
ResponseDTO resp(requestId, hmResp);
MessageDTO msg(m_bsp.getUUId(), message.getSourceId(), resp);
if (m_bsp.getUUId() != message.getSourceId()) {
return m_remoteQueue.push(msg);
}
return m_hostQueue.push(msg);
}

Expand All @@ -65,6 +71,9 @@ bool HiveMindHostApiRequestHandler::handleHiveMindHostApiRequest(
HiveMindHostApiResponseDTO hmResp(neighborResp);
ResponseDTO resp(requestId, hmResp);
MessageDTO msg(m_bsp.getUUId(), message.getSourceId(), resp);
if (m_bsp.getUUId() != message.getSourceId()) {
return m_remoteQueue.push(msg);
}
return m_hostQueue.push(msg);
}

Expand Down
1 change: 1 addition & 0 deletions src/os/freertos/include/freertos/FreeRTOSConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configSUPPORT_STATIC_ALLOCATION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configRECORD_STACK_HIGH_ADDRESS 1

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
Expand Down