mirror of
https://gitlab.com/hyperglitch/jellyfish.git
synced 2025-12-26 15:16:30 +00:00
123 lines
3.4 KiB
C
123 lines
3.4 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2025 Igor Brkic <igor@hyperglitch.com>
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*/
|
|
|
|
#include "jf_i2c.h"
|
|
#include <stdio.h>
|
|
#include "queue.h"
|
|
|
|
I2C_HandleTypeDef *hi2c_ptr = NULL;
|
|
static jf_i2c_request_t current_request = {0};
|
|
|
|
static uint8_t task_queue_buffer[sizeof(jf_i2c_request_t) * 10];
|
|
static StaticQueue_t task_queue_structure;
|
|
static QueueHandle_t task_queue;
|
|
|
|
|
|
static osThreadId_t task_handle;
|
|
static const osThreadAttr_t task_attributes = {
|
|
.name = "I2CTask",
|
|
.stack_size = 1024,
|
|
};
|
|
|
|
|
|
static void task_func(void *argument) {
|
|
(void) argument;
|
|
|
|
jf_i2c_request_t req;
|
|
|
|
while (true) {
|
|
// wait for a request
|
|
if (xQueueReceive(task_queue, &req, portMAX_DELAY) == pdTRUE) {
|
|
current_request = req; // save to global var so callbacks can notify the sender
|
|
|
|
// do the thing
|
|
if (req.cmd==JF_I2C_CMD_WRITE) {
|
|
HAL_I2C_Master_Transmit_IT(
|
|
hi2c_ptr,
|
|
req.addr<<1,
|
|
req.write_buffer,
|
|
req.size
|
|
);
|
|
}
|
|
else if (req.cmd==JF_I2C_CMD_READ) {
|
|
HAL_I2C_Master_Receive_IT(
|
|
hi2c_ptr,
|
|
req.addr<<1,
|
|
req.read_buffer,
|
|
req.size
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void jf_i2c_handle_callback(I2C_HandleTypeDef *hi2c) {
|
|
if (current_request.notify_task==NULL) {
|
|
return;
|
|
}
|
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
|
vTaskNotifyGiveFromISR(current_request.notify_task, &xHigherPriorityTaskWoken);
|
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
|
}
|
|
|
|
void jf_i2c_handle_error_callback(I2C_HandleTypeDef *hi2c) {
|
|
|
|
}
|
|
|
|
uint8_t i2c_write_buffer[128];
|
|
uint8_t i2c_read_buffer[128];
|
|
|
|
bool jf_i2c_add_to_queue(const jf_i2c_addr_t addr, const jf_i2c_cmd_t cmd, uint8_t *write_buffer, uint8_t *read_buffer, const uint16_t size, const bool blocking) {
|
|
jf_i2c_request_t req = {
|
|
.addr = addr,
|
|
.cmd = cmd,
|
|
.write_buffer = write_buffer,
|
|
.read_buffer = read_buffer,
|
|
.size = size,
|
|
.notify_task = NULL
|
|
};
|
|
if (blocking) {
|
|
req.notify_task = xTaskGetCurrentTaskHandle();
|
|
}
|
|
const BaseType_t ret = xQueueGenericSend(task_queue, &req, portMAX_DELAY, queueSEND_TO_BACK);
|
|
if (req.notify_task!=NULL) {
|
|
// wait for the request to complete
|
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
|
}
|
|
return ret==pdPASS;
|
|
}
|
|
|
|
bool jf_i2c_add_to_queue_from_isr(const jf_i2c_addr_t addr, const jf_i2c_cmd_t cmd, uint8_t *write_buffer, uint8_t *read_buffer, const uint16_t size) {
|
|
const jf_i2c_request_t req = {
|
|
.addr = addr,
|
|
.cmd = cmd,
|
|
.write_buffer = write_buffer,
|
|
.read_buffer = read_buffer,
|
|
.size = size,
|
|
.notify_task = NULL
|
|
};
|
|
const BaseType_t ret = xQueueGenericSendFromISR(task_queue, &req, pdFALSE, queueSEND_TO_BACK);
|
|
return ret==pdPASS;
|
|
}
|
|
|
|
void jf_i2c_init(I2C_HandleTypeDef *hi2c) {
|
|
hi2c_ptr = hi2c;
|
|
|
|
task_queue = xQueueCreateStatic(
|
|
10,
|
|
sizeof(jf_i2c_request_t),
|
|
task_queue_buffer,
|
|
&task_queue_structure
|
|
);
|
|
if(task_queue == NULL) {
|
|
printf("failed to create qspi queue\r\n");
|
|
Error_Handler();
|
|
}
|
|
|
|
task_handle = osThreadNew(task_func, NULL, &task_attributes);
|
|
printf("I2C task initialized\r\n");
|
|
}
|