Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bugs and improvements #101

Merged
merged 6 commits into from
Aug 29, 2024
Merged
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
1 change: 1 addition & 0 deletions inc/STM32PWM.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class STM32PWM {
STM32PWM(PinName pin, uint32_t frequency);
~STM32PWM() {}

void init();
void setFrequency(uint32_t freq);
void setDutyCyle(uint8_t percent);
void setDutyCycleFromResolution(uint32_t value, uint8_t resolution = 10);
Expand Down
133 changes: 133 additions & 0 deletions inc/drivers/daplink_flash/daplink_flash.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#pragma once

#include <STM32I2C.h>

#include <cinttypes>
#include <string>

namespace codal {

struct DapLinkFlash_Status_Register {
union {
struct {
/**
* @brief Reserved
*/
uint8_t RSV : 7;

/**
* @brief The flash is busy
*/
uint8_t busy : 1;
};
uint8_t status_register;
};
};

struct DapLinkFlash_Error_Register {
union {
struct {
/**
* @brief Parameters sent after command are invalid (For exemple: Too short or too long filename)
*/
uint8_t badParameter : 1;

/**
* @brief Reserved
*/
uint8_t RSV : 4;

/**
* @brief The file has reached its maximum size, and no more data can be added.
*/
uint8_t fillIsFull : 1;

/**
* @brief The filename contains invalid characters
*/
uint8_t badFilename : 1;

/**
* @brief The last command failed
*/
uint8_t lastCommandFailed : 1;
};
uint8_t error_register;
};
};

class DaplinkFlash {
public:
DaplinkFlash(STM32I2C& i2c, uint16_t address = 0x76);

/**
* @brief Get the device ID (0x4C)
*
* @return uint8_t
*/
uint8_t whoAmI();

/**
* @brief Defines the file name, using the 8.3 naming standard
*
* @param filename the filename string, must including the terminating null character
* @param extension the extension string, must including the terminating null character
* @return true if success, false otherwise
*/
bool setFilename(const char* filename, const char* extension);

/**
* @brief Read the filename save in flash
*
* @return std::string the filename (using the 8.3 naming standard)
*/
std::string getFilename();

/**
* @brief Erase entire flash
*
*/
void clearFlash();

/**
* @brief Save raw data in flash
*
* @param data data array
* @param length data array length
* @return uint16_t the number of bytes sent to the flash
*/
uint16_t writeData(uint8_t* data, uint16_t length);

/**
* @brief Save string in flash
*
* @param str The string to save. The string must contain a terminating null character.
*/
uint16_t writeString(const char* str);

uint16_t writeNumber(uint32_t val);

uint16_t writeFloat(float val, uint8_t precision);

/**
* @brief Get the Status Register
*
* @return DapLinkFlash_Status_Register
*/
DapLinkFlash_Status_Register getStatusRegister();

/**
* @brief Get the Error Register
*
* @return DapLinkFlash_Error_Register
*/
DapLinkFlash_Error_Register getErrorRegister();

private:
STM32I2C& i2c;
uint16_t address;

bool wait_busy(uint32_t timeout_ms);
};

} // namespace codal
1 change: 1 addition & 0 deletions inc/frameBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class FrameBuffer {
void drawSquare(uint16_t x, uint16_t y, uint16_t lenght, bool fill, uint16_t color);
void drawEllipse(int width, int height, int xCenter, int yCenter, bool fill, uint16_t color);
void drawCircle(int x, int y, int radius, bool fill, uint16_t color);
void drawArc(int x, int y, int radius, int start_angle, int end_angle, uint16_t color);
void drawPolygon(uint8_t x, uint8_t y, uint8_t line, uint8_t radius, uint8_t size, uint16_t color);
void drawMatrix(std::vector<std::vector<uint16_t>> matrix, unsigned x, unsigned y);

Expand Down
9 changes: 7 additions & 2 deletions source/STM32I2C.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ i2c_status_e STM32I2C::endTransmission(bool sendStop)

i2c_init(&i2c);

setXferOptions(sendStop);

i2c_status_e lastStatus;
unsigned packets = dataToSent.size() / getBufferSize();

Expand All @@ -52,6 +50,13 @@ i2c_status_e STM32I2C::endTransmission(bool sendStop)
auto offset = i * getBufferSize();
auto length = min<unsigned>(dataToSent.size() - offset, getBufferSize());

if (i == (packets - 1) && sendStop) {
setXferOptions(true);
}
else {
setXferOptions(false);
}

lastStatus = i2c_master_write(&i2c, currentAddress, dataToSent.data() + offset, length);

if (lastStatus != i2c_status_e::I2C_OK) break;
Expand Down
7 changes: 7 additions & 0 deletions source/STM32Pin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ int STM32Pin::setAnalogValue(int value)
// check if this pin has an analogue mode...
if (!(PIN_CAPABILITY_ANALOG & capability)) return DEVICE_NOT_SUPPORTED;

if (!(status & IO_STATUS_ANALOG_OUT)) {
disconnect();
pwm->init();

status = IO_STATUS_ANALOG_OUT;
}

// sanitise the level value
if (value < 0 || value > DEVICE_PIN_MAX_OUTPUT) return DEVICE_INVALID_PARAMETER;

Expand Down
2 changes: 1 addition & 1 deletion source/STM32SPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void STM32SPI::beginTransaction()
Error_Handler();
}

GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_TypeDef* port;

if (pin_sclk != NC) {
Expand Down
155 changes: 155 additions & 0 deletions source/drivers/daplink_flash/daplink_flash.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
#include "daplink_flash.h"

using namespace std;
using namespace codal;

constexpr uint8_t DAPFLASH_WHO_AM_I = 0x01;
constexpr uint8_t DAPFLASH_SET_FILENAME = 0x03;
constexpr uint8_t DAPFLASH_GET_FILENAME = 0x04;
constexpr uint8_t DAPFLASH_CLEAR_FLASH = 0x10;
constexpr uint8_t DAPFLASH_WRITE_DATA = 0x11;
constexpr uint8_t DAPFLASH_STATUS_REG = 0x80;
constexpr uint8_t DAPFLASH_ERROR_REG = 0x81;

constexpr uint16_t I2C_WRITE_DATA_LEN = 30;

DaplinkFlash::DaplinkFlash(STM32I2C& i2c, uint16_t address) : i2c{i2c}, address{address} {}

uint8_t DaplinkFlash::whoAmI()
{
return i2c.readRegister(address, DAPFLASH_WHO_AM_I, 1)[0];
}

bool DaplinkFlash::setFilename(const char* filename, const char* extension)
{
uint16_t len_file = strlen(filename);
uint16_t len_ext = strlen(extension);

if (len_file == 0) {
return false;
}

uint8_t data[11];

memset(data, 0x20, 11);

memcpy(data, filename, len_file <= 8 ? len_file : 8);
memcpy(data + 8, extension, len_ext <= 3 ? len_ext : 3);

if (!wait_busy(1000)) {
return false;
}

i2c.beginTransmission(address);
i2c.write(DAPFLASH_SET_FILENAME);
i2c.write(data, 11);
i2c.endTransmission();

return true;
}

string DaplinkFlash::getFilename()
{
if (!wait_busy(1000)) {
return "";
}

auto arr = i2c.readRegister(address, DAPFLASH_GET_FILENAME, 11);
return string((char*)arr.data(), 11);
}

void DaplinkFlash::clearFlash()
{
if (!wait_busy(1000)) {
return;
}

i2c.beginTransmission(address);
i2c.write(DAPFLASH_CLEAR_FLASH);
i2c.endTransmission();
}

uint16_t DaplinkFlash::writeData(uint8_t* data, uint16_t length)
{
uint16_t sent_data = 0;
uint16_t available;
uint16_t bytes_to_send;

while (sent_data < length) {
if (!wait_busy(1000)) {
break;
}

available = length - sent_data;
bytes_to_send = available > I2C_WRITE_DATA_LEN ? I2C_WRITE_DATA_LEN : available;

i2c.beginTransmission(address);
i2c.write(DAPFLASH_WRITE_DATA);
i2c.write(bytes_to_send);

for (uint16_t i = sent_data; i < (sent_data + bytes_to_send); ++i) {
i2c.write(data[i]);
}

for (uint16_t pad = bytes_to_send; pad < I2C_WRITE_DATA_LEN; ++pad) {
i2c.write(0x00);
}

i2c.endTransmission();

sent_data += bytes_to_send;
}

return sent_data;
}

uint16_t DaplinkFlash::writeString(const char* str)
{
return writeData((uint8_t*)str, strlen(str));
}

uint16_t DaplinkFlash::writeNumber(uint32_t val)
{
return writeString(to_string(val).c_str());
}

uint16_t DaplinkFlash::writeFloat(float val, uint8_t precision)
{
int ent = (int)val;
int dec = (int)((val - ent) * pow(10, precision));

return writeString((to_string(ent) + "," + to_string(dec)).c_str());
}

DapLinkFlash_Status_Register DaplinkFlash::getStatusRegister()
{
DapLinkFlash_Status_Register status;

status.status_register = i2c.readRegister(address, DAPFLASH_STATUS_REG, 1)[0];

return status;
}

DapLinkFlash_Error_Register DaplinkFlash::getErrorRegister()
{
DapLinkFlash_Error_Register error;

error.error_register = i2c.readRegister(address, DAPFLASH_ERROR_REG, 1)[0];

return error;
}

bool DaplinkFlash::wait_busy(uint32_t timeout_ms)
{
uint32_t start = getCurrentMillis();

while (getStatusRegister().busy == 1) {
if (getCurrentMillis() - start >= timeout_ms) {
printf("Wait timeout !");
return false;
}
printf("Wait...");
}

return true;
}
2 changes: 1 addition & 1 deletion source/drivers/joystick/joystick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
using namespace codal;

Joystick::Joystick(STM32Pin& horizontalAxisPin, STM32Pin& verticalAxisPin, STM32Pin& buttonPin, uint8_t deadzone)
: directionUserEvents({nullptr}), buttonUserEvents({nullptr})
: directionUserEvents{{nullptr}}, buttonUserEvents{{nullptr}}
{
horizontalSensor = new AnalogSensor(horizontalAxisPin, 6666);
verticalSensor = new AnalogSensor(verticalAxisPin, 9999);
Expand Down
12 changes: 12 additions & 0 deletions source/frameBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
using namespace codal;
using namespace std;

constexpr float deg_to_rad = F_PI / 180.0;

FrameBuffer::FrameBuffer(unsigned widthPixel, unsigned heightPixel, FrameBuffer::Format format)
: width(widthPixel), height(heightPixel), format(format)
{
Expand Down Expand Up @@ -362,6 +364,16 @@ void FrameBuffer::drawCircle(int x, int y, int radius, bool fill, uint16_t color
drawEllipse(radius * 2, radius * 2, x, y, fill, color);
}

void FrameBuffer::drawArc(int x, int y, int radius, int start_angle, int end_angle, uint16_t color)
{
float theta_rad = 0;

for (int theta = start_angle; theta <= end_angle; ++theta) {
theta_rad = theta * deg_to_rad;
drawPixel(x + radius * cos(theta_rad), y + radius * sin(theta_rad), color);
}
}

void FrameBuffer::drawPolygon(uint8_t x, uint8_t y, uint8_t line, uint8_t radius, uint8_t size, uint16_t color)
{
if (line < 3) return;
Expand Down
Loading
Loading