mirror of
https://github.com/Ralim/IronOS.git
synced 2025-02-26 07:53:55 +00:00
Rework _all_ of the I2C
This moves all of the I2C code to IRQ based (not DMA _yet_). But it does drastically improve reliability, especially of reads.
This commit is contained in:
@@ -84,7 +84,24 @@ uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void unstick_I2C() {
|
void unstick_I2C() {
|
||||||
// TODO
|
/* configure SDA/SCL for GPIO */
|
||||||
|
GPIO_BC(GPIOB) |= SDA_Pin|SCL_Pin;
|
||||||
|
gpio_init(SDA_GPIO_Port,GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SDA_Pin | SCL_Pin);
|
||||||
|
asm ("nop");
|
||||||
|
asm ("nop");
|
||||||
|
asm ("nop");
|
||||||
|
asm ("nop");
|
||||||
|
asm ("nop");
|
||||||
|
GPIO_BOP(GPIOB) |= SCL_Pin;
|
||||||
|
asm ("nop");
|
||||||
|
asm ("nop");
|
||||||
|
asm ("nop");
|
||||||
|
asm ("nop");
|
||||||
|
asm ("nop");
|
||||||
|
GPIO_BOP(GPIOB) |= SDA_Pin;
|
||||||
|
/* connect PB6 to I2C0_SCL */
|
||||||
|
/* connect PB7 to I2C0_SDA */
|
||||||
|
gpio_init(SDA_GPIO_Port, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, SDA_Pin | SCL_Pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t getButtonA() {
|
uint8_t getButtonA() {
|
||||||
|
|||||||
@@ -6,233 +6,15 @@
|
|||||||
*/
|
*/
|
||||||
#include "BSP.h"
|
#include "BSP.h"
|
||||||
#include "Setup.h"
|
#include "Setup.h"
|
||||||
|
#include "IRQ.h"
|
||||||
#include <I2C_Wrapper.hpp>
|
#include <I2C_Wrapper.hpp>
|
||||||
SemaphoreHandle_t FRToSI2C::I2CSemaphore = nullptr;
|
SemaphoreHandle_t FRToSI2C::I2CSemaphore = nullptr;
|
||||||
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
|
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
|
||||||
#define FLAG_TIMEOUT 1000
|
#define FLAG_TIMEOUT 1000
|
||||||
|
|
||||||
void FRToSI2C::CpltCallback() {
|
void FRToSI2C::CpltCallback() {
|
||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send START command
|
|
||||||
*
|
|
||||||
* @param obj The I2C object
|
|
||||||
*/
|
|
||||||
int i2c_start() {
|
|
||||||
int timeout;
|
|
||||||
|
|
||||||
/* clear I2C_FLAG_AERR Flag */
|
|
||||||
i2c_flag_clear(I2C0, I2C_FLAG_AERR);
|
|
||||||
|
|
||||||
/* wait until I2C_FLAG_I2CBSY flag is reset */
|
|
||||||
timeout = FLAG_TIMEOUT;
|
|
||||||
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET) {
|
|
||||||
if ((timeout--) == 0) {
|
|
||||||
|
|
||||||
return (int) -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ensure the i2c has been stopped */
|
|
||||||
timeout = FLAG_TIMEOUT;
|
|
||||||
while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP) == I2C_CTL0_STOP) {
|
|
||||||
if ((timeout--) == 0) {
|
|
||||||
return (int) -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* generate a START condition */
|
|
||||||
i2c_start_on_bus(I2C0);
|
|
||||||
|
|
||||||
/* ensure the i2c has been started successfully */
|
|
||||||
timeout = FLAG_TIMEOUT;
|
|
||||||
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) {
|
|
||||||
if ((timeout--) == 0) {
|
|
||||||
return (int) -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (int) 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Send STOP command
|
|
||||||
*
|
|
||||||
* @param obj The I2C object
|
|
||||||
*/
|
|
||||||
int i2c_stop() {
|
|
||||||
|
|
||||||
/* generate a STOP condition */
|
|
||||||
i2c_stop_on_bus(I2C0);
|
|
||||||
|
|
||||||
/* wait for STOP bit reset */
|
|
||||||
int timeout = FLAG_TIMEOUT;
|
|
||||||
while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP)) {
|
|
||||||
if ((timeout--) == 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Read one byte
|
|
||||||
*
|
|
||||||
* @param obj The I2C object
|
|
||||||
* @param last Acknoledge
|
|
||||||
* @return The read byte
|
|
||||||
*/
|
|
||||||
int i2c_byte_read(int last) {
|
|
||||||
int timeout;
|
|
||||||
|
|
||||||
if (last) {
|
|
||||||
/* disable acknowledge */
|
|
||||||
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
|
|
||||||
} else {
|
|
||||||
/* enable acknowledge */
|
|
||||||
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* wait until the byte is received */
|
|
||||||
timeout = FLAG_TIMEOUT;
|
|
||||||
while ((i2c_flag_get(I2C0, I2C_FLAG_RBNE)) == RESET) {
|
|
||||||
if ((timeout--) == 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (int) i2c_data_receive(I2C0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Write one byte
|
|
||||||
*
|
|
||||||
* @param obj The I2C object
|
|
||||||
* @param data Byte to be written
|
|
||||||
* @return 0 if NAK was received, 1 if ACK was received, 2 for timeout.
|
|
||||||
*/
|
|
||||||
int i2c_byte_write(int data) {
|
|
||||||
int timeout;
|
|
||||||
i2c_data_transmit(I2C0, data);
|
|
||||||
|
|
||||||
/* wait until the byte is transmitted */
|
|
||||||
timeout = FLAG_TIMEOUT;
|
|
||||||
while (((i2c_flag_get(I2C0, I2C_FLAG_TBE)) == RESET) || ((i2c_flag_get(I2C0, I2C_FLAG_BTC)) == RESET)) {
|
|
||||||
if ((timeout--) == 0) {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, uint16_t Size) {
|
|
||||||
if (!lock())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
uint32_t count = 0;
|
|
||||||
int timeout = 0;
|
|
||||||
|
|
||||||
/* wait until I2C_FLAG_I2CBSY flag is reset */
|
|
||||||
timeout = FLAG_TIMEOUT;
|
|
||||||
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET) {
|
|
||||||
if ((timeout--) == 0) {
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
if (timeout % 5 == 0) {
|
|
||||||
i2c_stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* generate a START condition */
|
|
||||||
i2c_start_on_bus(I2C0);
|
|
||||||
|
|
||||||
/* ensure the i2c has been started successfully */
|
|
||||||
timeout = FLAG_TIMEOUT;
|
|
||||||
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) {
|
|
||||||
if ((timeout--) == 0) {
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* send slave address */
|
|
||||||
i2c_master_addressing(I2C0, DevAddress, I2C_TRANSMITTER);
|
|
||||||
|
|
||||||
timeout = 0;
|
|
||||||
/* wait until I2C_FLAG_ADDSEND flag is set */
|
|
||||||
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
|
|
||||||
timeout++;
|
|
||||||
if (timeout > 100000) {
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool no_ack = i2c_flag_get(I2C0, I2C_FLAG_AERR);
|
|
||||||
no_ack |= i2c_flag_get(I2C0, I2C_FLAG_BERR);
|
|
||||||
if (no_ack) {
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/* clear ADDSEND */
|
|
||||||
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
|
|
||||||
int status = i2c_byte_write(MemAddress);
|
|
||||||
no_ack |= i2c_flag_get(I2C0, I2C_FLAG_BERR);
|
|
||||||
no_ack |= i2c_flag_get(I2C0, I2C_FLAG_LOSTARB);
|
|
||||||
if (status == 2 || no_ack) {
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//////////////////////////// //Restart into read
|
|
||||||
|
|
||||||
/* generate a START condition */
|
|
||||||
i2c_start_on_bus(I2C0);
|
|
||||||
|
|
||||||
/* ensure the i2c has been started successfully */
|
|
||||||
timeout = FLAG_TIMEOUT;
|
|
||||||
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) {
|
|
||||||
if ((timeout--) == 0) {
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* send slave address */
|
|
||||||
i2c_master_addressing(I2C0, DevAddress, I2C_RECEIVER);
|
|
||||||
|
|
||||||
timeout = 0;
|
|
||||||
/* wait until I2C_FLAG_ADDSEND flag is set */
|
|
||||||
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
|
|
||||||
timeout++;
|
|
||||||
if (timeout > 100000) {
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clear ADDSEND */
|
|
||||||
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
|
|
||||||
no_ack = i2c_flag_get(I2C0, I2C_FLAG_AERR);
|
|
||||||
if (no_ack) {
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (count = 0; count < Size; count++) {
|
|
||||||
pData[count] = i2c_byte_read(count == (Size - 1));
|
|
||||||
}
|
|
||||||
//Have nacked last data, so have to generate the stop sequence
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) {
|
bool FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) {
|
||||||
return Mem_Write(address, reg, &data, 1);
|
return Mem_Write(address, reg, &data, 1);
|
||||||
}
|
}
|
||||||
@@ -242,140 +24,114 @@ uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
|
|||||||
Mem_Read(add, reg, &temp, 1);
|
Mem_Read(add, reg, &temp, 1);
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, uint16_t Size) {
|
|
||||||
|
bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t read_address, uint8_t *p_buffer, uint16_t number_of_byte) {
|
||||||
|
if (!lock())
|
||||||
|
return false;
|
||||||
|
i2c_interrupt_disable(I2C0, I2C_INT_ERR);
|
||||||
|
i2c_interrupt_disable(I2C0, I2C_INT_BUF);
|
||||||
|
i2c_interrupt_disable(I2C0, I2C_INT_EV);
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_AERR);
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBALT);
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBTO);
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_OUERR);
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_LOSTARB);
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_BERR);
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_PECERR);
|
||||||
|
/* wait until I2C bus is idle */
|
||||||
|
uint8_t timeout = 0;
|
||||||
|
while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) {
|
||||||
|
timeout++;
|
||||||
|
osDelay(1);
|
||||||
|
if (timeout > 20) {
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i2c_slave_address = DevAddress;
|
||||||
|
i2c_read = p_buffer;
|
||||||
|
i2c_read_dress = read_address;
|
||||||
|
i2c_nbytes = number_of_byte;
|
||||||
|
i2c_error_code = 0;
|
||||||
|
i2c_process_flag = 1;
|
||||||
|
i2c_write_process = I2C_SEND_ADDRESS_FIRST;
|
||||||
|
i2c_read_process = I2C_SEND_ADDRESS_FIRST;
|
||||||
|
|
||||||
|
// if (2 == number_of_byte) {
|
||||||
|
// i2c_ackpos_config(I2C0, I2C_ACKPOS_NEXT);
|
||||||
|
// }
|
||||||
|
/* enable the I2C0 interrupt */
|
||||||
|
i2c_interrupt_enable(I2C0, I2C_INT_ERR);
|
||||||
|
i2c_interrupt_enable(I2C0, I2C_INT_EV);
|
||||||
|
i2c_interrupt_enable(I2C0, I2C_INT_BUF);
|
||||||
|
/* send a start condition to I2C bus */
|
||||||
|
i2c_start_on_bus(I2C0);
|
||||||
|
while ((i2c_nbytes > 0)) {
|
||||||
|
osDelay(1);
|
||||||
|
if (i2c_error_code != 0) {
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unlock();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *p_buffer, uint16_t number_of_byte) {
|
||||||
if (!lock())
|
if (!lock())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32_t count = 0;
|
i2c_slave_address = DevAddress;
|
||||||
int timeout = 0;
|
i2c_write = p_buffer;
|
||||||
|
i2c_write_dress = MemAddress;
|
||||||
/* wait until I2C_FLAG_I2CBSY flag is reset */
|
i2c_nbytes = number_of_byte;
|
||||||
timeout = FLAG_TIMEOUT;
|
i2c_error_code = 0;
|
||||||
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET) {
|
i2c_process_flag = 0;
|
||||||
if ((timeout--) == 0) {
|
i2c_write_process = I2C_SEND_ADDRESS_FIRST;
|
||||||
i2c_stop();
|
i2c_read_process = I2C_SEND_ADDRESS_FIRST;
|
||||||
unlock();
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_AERR);
|
||||||
return false;
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBALT);
|
||||||
} else {
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBTO);
|
||||||
if (timeout % 5 == 0) {
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_OUERR);
|
||||||
i2c_stop();
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_LOSTARB);
|
||||||
}
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_BERR);
|
||||||
}
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_PECERR);
|
||||||
}
|
/* enable the I2C0 interrupt */
|
||||||
/* generate a START condition */
|
i2c_interrupt_enable(I2C0, I2C_INT_ERR);
|
||||||
i2c_start_on_bus(I2C0);
|
i2c_interrupt_enable(I2C0, I2C_INT_EV);
|
||||||
|
i2c_interrupt_enable(I2C0, I2C_INT_BUF);
|
||||||
/* ensure the i2c has been started successfully */
|
/* wait until I2C bus is idle */
|
||||||
timeout = FLAG_TIMEOUT;
|
uint8_t timeout = 0;
|
||||||
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) {
|
while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) {
|
||||||
if ((timeout--) == 0) {
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* send slave address */
|
|
||||||
i2c_master_addressing(I2C0, DevAddress, I2C_TRANSMITTER);
|
|
||||||
|
|
||||||
timeout = 0;
|
|
||||||
/* wait until I2C_FLAG_ADDSEND flag is set */
|
|
||||||
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
|
|
||||||
timeout++;
|
timeout++;
|
||||||
if (timeout > 100000) {
|
osDelay(1);
|
||||||
i2c_stop();
|
if (timeout > 20) {
|
||||||
unlock();
|
unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear ADDSEND */
|
/* send a start condition to I2C bus */
|
||||||
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
|
//This sending will kickoff the IRQ's
|
||||||
int status = i2c_byte_write(MemAddress);
|
i2c_start_on_bus(I2C0);
|
||||||
for (count = 0; count < Size; count++) {
|
while ((i2c_nbytes > 0)) {
|
||||||
status = i2c_byte_write(pData[count]);
|
osDelay(1);
|
||||||
if (status != 1) {
|
if (i2c_error_code != 0) {
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if not sequential write, then send stop */
|
|
||||||
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
bool FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||||
if (!lock())
|
return Mem_Write(DevAddress, pData[0], pData + 1, Size - 1);
|
||||||
return false;
|
|
||||||
uint32_t count = 0;
|
|
||||||
int timeout = 0;
|
|
||||||
|
|
||||||
/* wait until I2C_FLAG_I2CBSY flag is reset */
|
|
||||||
timeout = FLAG_TIMEOUT;
|
|
||||||
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET) {
|
|
||||||
if ((timeout--) == 0) {
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
if (timeout % 5 == 0) {
|
|
||||||
i2c_stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* generate a START condition */
|
|
||||||
i2c_start_on_bus(I2C0);
|
|
||||||
|
|
||||||
/* ensure the i2c has been started successfully */
|
|
||||||
timeout = FLAG_TIMEOUT;
|
|
||||||
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) {
|
|
||||||
if ((timeout--) == 0) {
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* send slave address */
|
|
||||||
i2c_master_addressing(I2C0, DevAddress, I2C_TRANSMITTER);
|
|
||||||
|
|
||||||
timeout = 0;
|
|
||||||
/* wait until I2C_FLAG_ADDSEND flag is set */
|
|
||||||
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
|
|
||||||
timeout++;
|
|
||||||
if (timeout > 100000) {
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clear ADDSEND */
|
|
||||||
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
|
|
||||||
|
|
||||||
for (count = 0; count < Size; count++) {
|
|
||||||
int status = i2c_byte_write(pData[count]);
|
|
||||||
if (status != 1) {
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if not sequential write, then send stop */
|
|
||||||
|
|
||||||
i2c_stop();
|
|
||||||
unlock();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FRToSI2C::probe(uint16_t DevAddress) {
|
bool FRToSI2C::probe(uint16_t DevAddress) {
|
||||||
uint8_t temp = 0;
|
uint8_t temp[1];
|
||||||
return Mem_Read(DevAddress, 0x00, &temp, 1);
|
return Mem_Read(DevAddress, 0x00, temp, sizeof(temp));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FRToSI2C::I2C_Unstick() {
|
void FRToSI2C::I2C_Unstick() {
|
||||||
@@ -384,15 +140,12 @@ void FRToSI2C::I2C_Unstick() {
|
|||||||
|
|
||||||
bool FRToSI2C::lock() {
|
bool FRToSI2C::lock() {
|
||||||
if (I2CSemaphore == nullptr) {
|
if (I2CSemaphore == nullptr) {
|
||||||
for (;;) { //
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return xSemaphoreTake(I2CSemaphore,1000) == pdTRUE;
|
return xSemaphoreTake(I2CSemaphore,1000) == pdTRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FRToSI2C::unlock() {
|
void FRToSI2C::unlock() {
|
||||||
if (I2CSemaphore == nullptr)
|
|
||||||
return;
|
|
||||||
xSemaphoreGive(I2CSemaphore);
|
xSemaphoreGive(I2CSemaphore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,16 @@
|
|||||||
#include "IRQ.h"
|
#include "IRQ.h"
|
||||||
#include "Pins.h"
|
#include "Pins.h"
|
||||||
#include "int_n.h"
|
#include "int_n.h"
|
||||||
|
volatile uint8_t i2c_read_process = 0;
|
||||||
|
volatile uint8_t i2c_write_process = 0;
|
||||||
|
volatile uint8_t i2c_slave_address = 0;
|
||||||
|
volatile uint8_t i2c_error_code = 0;
|
||||||
|
volatile uint8_t* i2c_write;
|
||||||
|
volatile uint8_t* i2c_read;
|
||||||
|
volatile uint16_t i2c_nbytes;
|
||||||
|
volatile uint16_t i2c_write_dress;
|
||||||
|
volatile uint16_t i2c_read_dress;
|
||||||
|
volatile uint8_t i2c_process_flag = 0;
|
||||||
void ADC0_1_IRQHandler(void) {
|
void ADC0_1_IRQHandler(void) {
|
||||||
|
|
||||||
adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOIC);
|
adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOIC);
|
||||||
@@ -39,8 +49,7 @@ void TIMER1_IRQHandler(void) {
|
|||||||
|
|
||||||
timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_0, 0);
|
timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_0, 0);
|
||||||
if (pendingPWM) {
|
if (pendingPWM) {
|
||||||
timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1,
|
timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, pendingPWM);
|
||||||
pendingPWM);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,16 +62,221 @@ void setTipPWM(uint8_t pulse) {
|
|||||||
pendingPWM = pulse;
|
pendingPWM = pulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EXTI5_9_IRQHandler(void) {
|
||||||
void EXTI5_9_IRQHandler(void)
|
|
||||||
{
|
|
||||||
#ifdef POW_PD
|
#ifdef POW_PD
|
||||||
if (RESET != exti_interrupt_flag_get(EXTI_5)){
|
if (RESET != exti_interrupt_flag_get(EXTI_5)) {
|
||||||
exti_interrupt_flag_clear(EXTI_5);
|
exti_interrupt_flag_clear(EXTI_5);
|
||||||
|
|
||||||
if(RESET == gpio_input_bit_get(FUSB302_IRQ_GPIO_Port, FUSB302_IRQ_Pin)){
|
if (RESET == gpio_input_bit_get(FUSB302_IRQ_GPIO_Port, FUSB302_IRQ_Pin)) {
|
||||||
InterruptHandler::irqCallback();
|
InterruptHandler::irqCallback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief handle I2C0 event interrupt request
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void I2C0_EV_IRQHandler(void) {
|
||||||
|
if (RESET == i2c_process_flag) {
|
||||||
|
switch (i2c_write_process) {
|
||||||
|
case I2C_SEND_ADDRESS_FIRST:
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SBSEND)) {
|
||||||
|
/* send slave address */
|
||||||
|
i2c_master_addressing(I2C0, i2c_slave_address, I2C_TRANSMITTER);
|
||||||
|
i2c_write_process = I2C_CLEAR_ADDRESS_FLAG_FIRST;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_CLEAR_ADDRESS_FLAG_FIRST:
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_ADDSEND)) {
|
||||||
|
/*clear ADDSEND bit */
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_ADDSEND);
|
||||||
|
i2c_write_process = I2C_TRANSMIT_WRITE_READ_ADD;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_TRANSMIT_WRITE_READ_ADD:
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE)) {
|
||||||
|
i2c_data_transmit(I2C0, i2c_write_dress);
|
||||||
|
/* wait until BTC bit is set */
|
||||||
|
while (!i2c_flag_get(I2C0, I2C_FLAG_BTC))
|
||||||
|
;
|
||||||
|
i2c_write_process = I2C_TRANSMIT_DATA;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_TRANSMIT_DATA:
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE)) {
|
||||||
|
/* the master sends a data byte */
|
||||||
|
i2c_data_transmit(I2C0, *i2c_write++);
|
||||||
|
i2c_nbytes--;
|
||||||
|
if (RESET == i2c_nbytes) {
|
||||||
|
i2c_write_process = I2C_STOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_STOP:
|
||||||
|
/* the master sends a stop condition to I2C bus */
|
||||||
|
i2c_stop_on_bus(I2C0);
|
||||||
|
/* disable the I2C0 interrupt */
|
||||||
|
i2c_interrupt_disable(I2C0, I2C_INT_ERR);
|
||||||
|
i2c_interrupt_disable(I2C0, I2C_INT_BUF);
|
||||||
|
i2c_interrupt_disable(I2C0, I2C_INT_EV);
|
||||||
|
i2c_write_process = I2C_SEND_ADDRESS_FIRST;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (SET == i2c_process_flag) {
|
||||||
|
switch (i2c_read_process) {
|
||||||
|
case I2C_SEND_ADDRESS_FIRST:
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SBSEND)) {
|
||||||
|
/* send slave address */
|
||||||
|
i2c_master_addressing(I2C0, i2c_slave_address, I2C_TRANSMITTER);
|
||||||
|
i2c_read_process = I2C_CLEAR_ADDRESS_FLAG_FIRST;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_CLEAR_ADDRESS_FLAG_FIRST:
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_ADDSEND)) {
|
||||||
|
/*clear ADDSEND bit */
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_ADDSEND);
|
||||||
|
i2c_read_process = I2C_TRANSMIT_WRITE_READ_ADD;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_TRANSMIT_WRITE_READ_ADD:
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE)) {
|
||||||
|
i2c_data_transmit(I2C0, i2c_read_dress);
|
||||||
|
/* wait until BTC bit is set */
|
||||||
|
while (!i2c_flag_get(I2C0, I2C_FLAG_BTC))
|
||||||
|
;
|
||||||
|
/* send a start condition to I2C bus */
|
||||||
|
i2c_start_on_bus(I2C0);
|
||||||
|
i2c_read_process = I2C_SEND_ADDRESS_SECOND;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_SEND_ADDRESS_SECOND:
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SBSEND)) {
|
||||||
|
i2c_master_addressing(I2C0, i2c_slave_address, I2C_RECEIVER);
|
||||||
|
if ((1 == i2c_nbytes) || (2 == i2c_nbytes)) {
|
||||||
|
i2c_ackpos_config(I2C0, i2c_nbytes == 1 ? I2C_ACKPOS_CURRENT : I2C_ACKPOS_NEXT);
|
||||||
|
/* clear the ACKEN before the ADDSEND is cleared */
|
||||||
|
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
|
||||||
|
} else {
|
||||||
|
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
|
||||||
|
|
||||||
|
}
|
||||||
|
i2c_read_process = I2C_CLEAR_ADDRESS_FLAG_SECOND;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_CLEAR_ADDRESS_FLAG_SECOND:
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_ADDSEND)) {
|
||||||
|
|
||||||
|
/*clear ADDSEND bit */
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_ADDSEND);
|
||||||
|
i2c_read_process = I2C_TRANSMIT_DATA;
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_TRANSMIT_DATA:
|
||||||
|
if (i2c_nbytes > 0) {
|
||||||
|
/* read a byte from the EEPROM */
|
||||||
|
if (i2c_nbytes == 2) {
|
||||||
|
/* wait until BTC bit is set */
|
||||||
|
i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT);
|
||||||
|
/* clear the ACKEN before the ADDSEND is cleared */
|
||||||
|
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
|
||||||
|
}
|
||||||
|
*i2c_read = i2c_data_receive(I2C0);
|
||||||
|
i2c_read++;
|
||||||
|
i2c_nbytes--;
|
||||||
|
if (i2c_nbytes == 0) {
|
||||||
|
/* the master sends a stop condition to I2C bus */
|
||||||
|
i2c_stop_on_bus(I2C0);
|
||||||
|
/* disable the I2C0 interrupt */
|
||||||
|
i2c_interrupt_disable(I2C0, I2C_INT_ERR);
|
||||||
|
i2c_interrupt_disable(I2C0, I2C_INT_BUF);
|
||||||
|
i2c_interrupt_disable(I2C0, I2C_INT_EV);
|
||||||
|
i2c_process_flag = RESET;
|
||||||
|
i2c_read_process = I2C_DONE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i2c_read_process = I2C_STOP;
|
||||||
|
/* the master sends a stop condition to I2C bus */
|
||||||
|
i2c_stop_on_bus(I2C0);
|
||||||
|
/* disable the I2C0 interrupt */
|
||||||
|
i2c_interrupt_disable(I2C0, I2C_INT_ERR);
|
||||||
|
i2c_interrupt_disable(I2C0, I2C_INT_BUF);
|
||||||
|
i2c_interrupt_disable(I2C0, I2C_INT_EV);
|
||||||
|
i2c_process_flag = RESET;
|
||||||
|
i2c_read_process = I2C_DONE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case I2C_STOP:
|
||||||
|
/* the master sends a stop condition to I2C bus */
|
||||||
|
i2c_stop_on_bus(I2C0);
|
||||||
|
/* disable the I2C0 interrupt */
|
||||||
|
i2c_interrupt_disable(I2C0, I2C_INT_ERR);
|
||||||
|
i2c_interrupt_disable(I2C0, I2C_INT_BUF);
|
||||||
|
i2c_interrupt_disable(I2C0, I2C_INT_EV);
|
||||||
|
i2c_process_flag = RESET;
|
||||||
|
i2c_read_process = I2C_DONE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief handle I2C0 error interrupt request
|
||||||
|
\param[in] none
|
||||||
|
\param[out] none
|
||||||
|
\retval none
|
||||||
|
*/
|
||||||
|
void I2C0_ER_IRQHandler(void) {
|
||||||
|
/* no acknowledge received */
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_AERR)) {
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_AERR);
|
||||||
|
i2c_error_code = 1; //NAK
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SMBus alert */
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SMBALT)) {
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBALT);
|
||||||
|
i2c_error_code = 2; //SMB Alert
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bus timeout in SMBus mode */
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SMBTO)) {
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBTO);
|
||||||
|
i2c_error_code = 3; //SMB Timeout
|
||||||
|
}
|
||||||
|
|
||||||
|
/* over-run or under-run when SCL stretch is disabled */
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_OUERR)) {
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_OUERR);
|
||||||
|
i2c_error_code = 4; //OverRun
|
||||||
|
}
|
||||||
|
|
||||||
|
/* arbitration lost */
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_LOSTARB)) {
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_LOSTARB);
|
||||||
|
i2c_error_code = 5; //Lost ARB -- multi master -- shouldnt happen
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bus error */
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_BERR)) {
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_BERR);
|
||||||
|
i2c_error_code = 6; //Bus Error
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CRC value doesn't match */
|
||||||
|
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_PECERR)) {
|
||||||
|
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_PECERR);
|
||||||
|
i2c_error_code = 7; //CRC Fail -- Shouldnt Happen
|
||||||
|
}
|
||||||
|
|
||||||
|
i2c_stop_on_bus(I2C0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,6 +20,31 @@ extern "C" {
|
|||||||
void ADC0_1_IRQHandler(void);
|
void ADC0_1_IRQHandler(void);
|
||||||
void TIMER1_IRQHandler(void);
|
void TIMER1_IRQHandler(void);
|
||||||
void EXTI5_9_IRQHandler(void);
|
void EXTI5_9_IRQHandler(void);
|
||||||
|
/* handle I2C0 event interrupt request */
|
||||||
|
void I2C0_EV_IRQHandler(void);
|
||||||
|
/* handle I2C0 error interrupt request */
|
||||||
|
void I2C0_ER_IRQHandler(void);
|
||||||
|
typedef enum {
|
||||||
|
I2C_SEND_ADDRESS_FIRST = 0, //Sending slave address
|
||||||
|
I2C_CLEAR_ADDRESS_FLAG_FIRST, // Clear address send
|
||||||
|
I2C_TRANSMIT_WRITE_READ_ADD, //Transmit the memory address to read/write from
|
||||||
|
I2C_SEND_ADDRESS_SECOND, //Send address again for read
|
||||||
|
I2C_CLEAR_ADDRESS_FLAG_SECOND, //Clear address again
|
||||||
|
I2C_TRANSMIT_DATA, //Transmit recieve data
|
||||||
|
I2C_STOP, //Send stop
|
||||||
|
I2C_ABORTED, //
|
||||||
|
I2C_DONE,// I2C transfer is complete
|
||||||
|
} i2c_process_enum;
|
||||||
|
extern volatile uint8_t i2c_slave_address;
|
||||||
|
extern volatile uint8_t i2c_read_process;
|
||||||
|
extern volatile uint8_t i2c_write_process;
|
||||||
|
extern volatile uint8_t i2c_error_code;
|
||||||
|
extern volatile uint8_t* i2c_write;
|
||||||
|
extern volatile uint8_t* i2c_read;
|
||||||
|
extern volatile uint16_t i2c_nbytes;
|
||||||
|
extern volatile uint16_t i2c_write_dress;
|
||||||
|
extern volatile uint16_t i2c_read_dress;
|
||||||
|
extern volatile uint8_t i2c_process_flag;
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
#define POW_QC
|
#define POW_QC
|
||||||
#define TEMP_TMP36
|
#define TEMP_TMP36
|
||||||
#define ACCEL_BMA
|
#define ACCEL_BMA
|
||||||
|
|
||||||
|
|
||||||
#define BATTFILTERDEPTH 32
|
#define BATTFILTERDEPTH 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -65,8 +65,7 @@ void setup_gpio() {
|
|||||||
gpio_init(OLED_RESET_GPIO_Port, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ,
|
gpio_init(OLED_RESET_GPIO_Port, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ,
|
||||||
OLED_RESET_Pin);
|
OLED_RESET_Pin);
|
||||||
//I2C as AF Open Drain
|
//I2C as AF Open Drain
|
||||||
gpio_init(SDA_GPIO_Port, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, SDA_Pin);
|
gpio_init(SDA_GPIO_Port, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, SDA_Pin | SCL_Pin);
|
||||||
gpio_init(SCL_GPIO_Port, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, SCL_Pin);
|
|
||||||
//PWM output as AF Push Pull
|
//PWM output as AF Push Pull
|
||||||
gpio_init(PWM_Out_GPIO_Port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ,
|
gpio_init(PWM_Out_GPIO_Port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ,
|
||||||
PWM_Out_Pin);
|
PWM_Out_Pin);
|
||||||
@@ -126,11 +125,13 @@ void setup_i2c() {
|
|||||||
/* enable I2C0 clock */
|
/* enable I2C0 clock */
|
||||||
rcu_periph_clock_enable(RCU_I2C0);
|
rcu_periph_clock_enable(RCU_I2C0);
|
||||||
//Setup I20 at 400kHz
|
//Setup I20 at 400kHz
|
||||||
i2c_clock_config(I2C0, 100 * 1000, I2C_DTCY_16_9);
|
i2c_clock_config(I2C0, 400 * 1000, I2C_DTCY_2);
|
||||||
i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x00);
|
i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x00);
|
||||||
i2c_enable(I2C0);
|
i2c_enable(I2C0);
|
||||||
/* enable acknowledge */
|
/* enable acknowledge */
|
||||||
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
|
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
|
||||||
|
eclic_irq_enable(I2C0_EV_IRQn,1,0);
|
||||||
|
eclic_irq_enable(I2C0_ER_IRQn,2,0);
|
||||||
}
|
}
|
||||||
void setup_adc() {
|
void setup_adc() {
|
||||||
|
|
||||||
|
|||||||
117
workspace/TS100/Core/BSP/Pine64/Vendor/Lib/I2C0_IE.c
vendored
117
workspace/TS100/Core/BSP/Pine64/Vendor/Lib/I2C0_IE.c
vendored
@@ -1,117 +0,0 @@
|
|||||||
/*!
|
|
||||||
\file I2C0_IE.c
|
|
||||||
\brief I2C0 master transmitter interrupt program
|
|
||||||
|
|
||||||
\version 2019-06-05, V1.0.0, firmware for GD32VF103
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright (c) 2019, GigaDevice Semiconductor Inc.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
3. Neither the name of the copyright holder nor the names of its contributors
|
|
||||||
may be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
||||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
|
||||||
OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "gd32vf103_i2c.h"
|
|
||||||
|
|
||||||
#include "I2C_IE.h"
|
|
||||||
|
|
||||||
uint32_t event1;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief handle I2C0 event interrupt request
|
|
||||||
\param[in] none
|
|
||||||
\param[out] none
|
|
||||||
\retval none
|
|
||||||
*/
|
|
||||||
void I2C0_EventIRQ_Handler(void) {
|
|
||||||
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SBSEND)) {
|
|
||||||
/* send slave address */
|
|
||||||
i2c_master_addressing(I2C0, I2C1_SLAVE_ADDRESS7, I2C_TRANSMITTER);
|
|
||||||
} else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_ADDSEND)) {
|
|
||||||
/*clear ADDSEND bit */
|
|
||||||
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_ADDSEND);
|
|
||||||
} else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE)) {
|
|
||||||
if (I2C_nBytes > 0) {
|
|
||||||
/* the master sends a data byte */
|
|
||||||
i2c_data_transmit(I2C0, *i2c_txbuffer++);
|
|
||||||
I2C_nBytes--;
|
|
||||||
} else {
|
|
||||||
/* the master sends a stop condition to I2C bus */
|
|
||||||
i2c_stop_on_bus(I2C0);
|
|
||||||
/* disable the I2C0 interrupt */
|
|
||||||
i2c_interrupt_disable(I2C0, I2C_INT_ERR);
|
|
||||||
i2c_interrupt_disable(I2C0, I2C_INT_BUF);
|
|
||||||
i2c_interrupt_disable(I2C0, I2C_INT_EV);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief handle I2C0 error interrupt request
|
|
||||||
\param[in] none
|
|
||||||
\param[out] none
|
|
||||||
\retval none
|
|
||||||
*/
|
|
||||||
void I2C0_ErrorIRQ_Handler(void) {
|
|
||||||
/* no acknowledge received */
|
|
||||||
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_AERR)) {
|
|
||||||
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_AERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* SMBus alert */
|
|
||||||
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SMBALT)) {
|
|
||||||
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBALT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* bus timeout in SMBus mode */
|
|
||||||
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SMBTO)) {
|
|
||||||
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBTO);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* over-run or under-run when SCL stretch is disabled */
|
|
||||||
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_OUERR)) {
|
|
||||||
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_OUERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* arbitration lost */
|
|
||||||
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_LOSTARB)) {
|
|
||||||
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_LOSTARB);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* bus error */
|
|
||||||
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_BERR)) {
|
|
||||||
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_BERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CRC value doesn't match */
|
|
||||||
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_PECERR)) {
|
|
||||||
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_PECERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* disable the error interrupt */
|
|
||||||
i2c_interrupt_disable(I2C0, I2C_INT_ERR);
|
|
||||||
i2c_interrupt_disable(I2C0, I2C_INT_BUF);
|
|
||||||
i2c_interrupt_disable(I2C0, I2C_INT_EV);
|
|
||||||
}
|
|
||||||
112
workspace/TS100/Core/BSP/Pine64/Vendor/Lib/I2C1_IE.c
vendored
112
workspace/TS100/Core/BSP/Pine64/Vendor/Lib/I2C1_IE.c
vendored
@@ -1,112 +0,0 @@
|
|||||||
/*!
|
|
||||||
\file I2C1_IE.c
|
|
||||||
\brief I2C1 slave receiver interrupt program
|
|
||||||
|
|
||||||
\version 2019-06-05, V1.0.0, firmware for GD32VF103
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright (c) 2019, GigaDevice Semiconductor Inc.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
3. Neither the name of the copyright holder nor the names of its contributors
|
|
||||||
may be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
||||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
|
||||||
OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "gd32vf103_i2c.h"
|
|
||||||
|
|
||||||
#include "I2C_IE.h"
|
|
||||||
|
|
||||||
uint32_t event2;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief handle I2C1 event interrupt request
|
|
||||||
\param[in] none
|
|
||||||
\param[out] none
|
|
||||||
\retval none
|
|
||||||
*/
|
|
||||||
void I2C1_EventIRQ_Handler(void) {
|
|
||||||
if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_ADDSEND)) {
|
|
||||||
/* clear the ADDSEND bit */
|
|
||||||
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_ADDSEND);
|
|
||||||
} else if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_RBNE)) {
|
|
||||||
/* if reception data register is not empty ,I2C1 will read a data from I2C_DATA */
|
|
||||||
*i2c_rxbuffer++ = i2c_data_receive(I2C1);
|
|
||||||
} else if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_STPDET)) {
|
|
||||||
status = SUCCESS;
|
|
||||||
/* clear the STPDET bit */
|
|
||||||
i2c_enable(I2C1);
|
|
||||||
/* disable I2C1 interrupt */
|
|
||||||
i2c_interrupt_disable(I2C1, I2C_INT_ERR);
|
|
||||||
i2c_interrupt_disable(I2C1, I2C_INT_BUF);
|
|
||||||
i2c_interrupt_disable(I2C1, I2C_INT_EV);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief handle I2C1 error interrupt request
|
|
||||||
\param[in] none
|
|
||||||
\param[out] none
|
|
||||||
\retval none
|
|
||||||
*/
|
|
||||||
void I2C1_ErrorIRQ_Handler(void) {
|
|
||||||
/* no acknowledge received */
|
|
||||||
if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_AERR)) {
|
|
||||||
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_AERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* SMBus alert */
|
|
||||||
if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SMBALT)) {
|
|
||||||
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_SMBALT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* bus timeout in SMBus mode */
|
|
||||||
if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SMBTO)) {
|
|
||||||
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_SMBTO);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* over-run or under-run when SCL stretch is disabled */
|
|
||||||
if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_OUERR)) {
|
|
||||||
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_OUERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* arbitration lost */
|
|
||||||
if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_LOSTARB)) {
|
|
||||||
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_LOSTARB);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* bus error */
|
|
||||||
if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_BERR)) {
|
|
||||||
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_BERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CRC value doesn't match */
|
|
||||||
if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_PECERR)) {
|
|
||||||
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_PECERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* disable the error interrupt */
|
|
||||||
i2c_interrupt_disable(I2C1, I2C_INT_ERR);
|
|
||||||
i2c_interrupt_disable(I2C1, I2C_INT_BUF);
|
|
||||||
i2c_interrupt_disable(I2C1, I2C_INT_EV);
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
/*!
|
|
||||||
\file I2C1_IE.c
|
|
||||||
\brief The header file of I2C0 and I2C1 interrupt
|
|
||||||
|
|
||||||
\version 2019-06-05, V1.0.0, firmware for GD32VF103
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright (c) 2019, GigaDevice Semiconductor Inc.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
3. Neither the name of the copyright holder nor the names of its contributors
|
|
||||||
may be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
||||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
|
||||||
OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
#ifndef I2C_IE_H
|
|
||||||
#define I2C_IE_H
|
|
||||||
|
|
||||||
#include "gd32vf103.h"
|
|
||||||
|
|
||||||
#define I2C0_SLAVE_ADDRESS7 0x82
|
|
||||||
#define I2C1_SLAVE_ADDRESS7 0x72
|
|
||||||
|
|
||||||
extern volatile ErrStatus status;
|
|
||||||
extern volatile uint8_t *i2c_txbuffer;
|
|
||||||
extern volatile uint8_t *i2c_rxbuffer;
|
|
||||||
extern volatile uint16_t I2C_nBytes;
|
|
||||||
|
|
||||||
/* function declarations */
|
|
||||||
/* handle I2C0 event interrupt request */
|
|
||||||
void I2C0_EventIRQ_Handler(void);
|
|
||||||
/* handle I2C0 error interrupt request */
|
|
||||||
void I2C0_ErrorIRQ_Handler(void);
|
|
||||||
/* handle I2C1 event interrupt request */
|
|
||||||
void I2C1_EventIRQ_Handler(void);
|
|
||||||
/* handle I2C1 error interrupt request */
|
|
||||||
void I2C1_ErrorIRQ_Handler(void);
|
|
||||||
|
|
||||||
#endif /* I2C_IE_H */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -134,12 +134,19 @@ void fusb_send_hardrst() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void fusb_setup() {
|
void fusb_setup() {
|
||||||
|
if (!FRToSI2C::probe(FUSB302B_ADDR)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* Fully reset the FUSB302B */
|
/* Fully reset the FUSB302B */
|
||||||
fusb_write_byte( FUSB_RESET, FUSB_RESET_SW_RES);
|
fusb_write_byte( FUSB_RESET, FUSB_RESET_SW_RES);
|
||||||
osDelay(2);
|
osDelay(2);
|
||||||
|
uint8_t tries = 0;
|
||||||
while (!fusb_read_id()) {
|
while (!fusb_read_id()) {
|
||||||
osDelay(10);
|
osDelay(10);
|
||||||
|
tries++;
|
||||||
|
if (tries > 5) {
|
||||||
|
return; //Welp :(
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Turn on all power */
|
/* Turn on all power */
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include <BMA223.hpp>
|
#include <BMA223.hpp>
|
||||||
#include "BMA223_defines.h"
|
#include "BMA223_defines.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
#define BMA223_ADDRESS 0b00110000
|
#define BMA223_ADDRESS 0x18<<1
|
||||||
|
|
||||||
bool BMA223::detect() {
|
bool BMA223::detect() {
|
||||||
return FRToSI2C::probe(BMA223_ADDRESS);
|
return FRToSI2C::probe(BMA223_ADDRESS);
|
||||||
@@ -16,16 +16,17 @@ bool BMA223::detect() {
|
|||||||
|
|
||||||
static const FRToSI2C::I2C_REG i2c_registers[] = { //
|
static const FRToSI2C::I2C_REG i2c_registers[] = { //
|
||||||
//
|
//
|
||||||
{ BMA223_PMU_RANGE, 0b0011, 0 }, //2G range
|
{ BMA223_PMU_RANGE, 0b00000011, 0 }, //2G range
|
||||||
{ BMA223_PMU_BW, 0b1101, 0 }, //250Hz filter
|
{ BMA223_PMU_BW, 0b00001101, 0 }, //250Hz filter
|
||||||
{ BMA223_PMU_LPW, 0x00, 0 }, //Full power
|
{ BMA223_PMU_LPW, 0b00000000, 0 }, //Full power
|
||||||
{ BMA223_ACCD_HBW, 0b01000000, 0 }, //filtered data out
|
{ BMA223_ACCD_HBW, 0b00000000, 0 }, //filtered data out
|
||||||
{ BMA223_INT_OUT_CTRL, 0b1111, 0 }, //interrupt active high and OD to get it hi-z
|
{ BMA223_INT_OUT_CTRL, 0b00001010, 0 }, //interrupt active low and OD to get it hi-z
|
||||||
{ BMA223_OFC_CTRL, 0b00000111, 0 }, //High pass en
|
{ BMA223_INT_RST_LATCH, 0b10000000, 0 }, //interrupt active low and OD to get it hi-z
|
||||||
|
// { BMA223_OFC_CTRL, 0b00000111, 0 }, //High pass en
|
||||||
|
|
||||||
//
|
//
|
||||||
};
|
};
|
||||||
void BMA223::initalize() {
|
bool BMA223::initalize() {
|
||||||
//Setup acceleration readings
|
//Setup acceleration readings
|
||||||
//2G range
|
//2G range
|
||||||
//bandwidth = 250Hz
|
//bandwidth = 250Hz
|
||||||
@@ -35,19 +36,22 @@ void BMA223::initalize() {
|
|||||||
// Hysteresis is set to ~ 16 counts
|
// Hysteresis is set to ~ 16 counts
|
||||||
//Theta blocking is set to 0b10
|
//Theta blocking is set to 0b10
|
||||||
|
|
||||||
FRToSI2C::writeRegistersBulk(BMA223_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0]));
|
return FRToSI2C::writeRegistersBulk(BMA223_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0]));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BMA223::getAxisReadings(int16_t& x, int16_t& y, int16_t& z) {
|
void BMA223::getAxisReadings(int16_t& x, int16_t& y, int16_t& z) {
|
||||||
//The BMA is odd in that its output data width is only 8 bits
|
//The BMA is odd in that its output data width is only 8 bits
|
||||||
//And yet there are MSB and LSB registers _sigh_.
|
//And yet there are MSB and LSB registers _sigh_.
|
||||||
uint8_t sensorData[6];
|
uint8_t sensorData[6] = { 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
FRToSI2C::Mem_Read(BMA223_ADDRESS, BMA223_ACCD_X_LSB, sensorData, 6);
|
if (FRToSI2C::Mem_Read(BMA223_ADDRESS, BMA223_ACCD_X_LSB, sensorData, 6) == false) {
|
||||||
|
x = 0xAAFF;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
x = sensorData[1] << 2;
|
x = sensorData[1] << 4;
|
||||||
y = sensorData[3] << 2;
|
y = sensorData[3] << 4;
|
||||||
z = sensorData[5] << 2;
|
z = sensorData[5] << 4;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
class BMA223 {
|
class BMA223 {
|
||||||
public:
|
public:
|
||||||
static bool detect();
|
static bool detect();
|
||||||
static void initalize();
|
static bool initalize();
|
||||||
//1 = rh, 2,=lh, 8=flat
|
//1 = rh, 2,=lh, 8=flat
|
||||||
static Orientation getOrientation() {
|
static Orientation getOrientation() {
|
||||||
#ifdef ACCEL_ORI_FLIP
|
#ifdef ACCEL_ORI_FLIP
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ static const FRToSI2C::I2C_REG i2c_registers[] = { { LIS_CTRL_REG1, 0x17, 0 }, /
|
|||||||
{ LIS_INT1_THS, 0x28, 0 }, //
|
{ LIS_INT1_THS, 0x28, 0 }, //
|
||||||
{ LIS_INT1_DURATION, 64, 0 } };
|
{ LIS_INT1_DURATION, 64, 0 } };
|
||||||
|
|
||||||
void LIS2DH12::initalize() {
|
bool LIS2DH12::initalize() {
|
||||||
FRToSI2C::writeRegistersBulk(LIS2DH_I2C_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0]));
|
return FRToSI2C::writeRegistersBulk(LIS2DH_I2C_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LIS2DH12::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
void LIS2DH12::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
class LIS2DH12 {
|
class LIS2DH12 {
|
||||||
public:
|
public:
|
||||||
static bool detect();
|
static bool detect();
|
||||||
static void initalize();
|
static bool initalize();
|
||||||
//1 = rh, 2,=lh, 8=flat
|
//1 = rh, 2,=lh, 8=flat
|
||||||
static Orientation getOrientation() {
|
static Orientation getOrientation() {
|
||||||
#ifdef LIS_ORI_FLIP
|
#ifdef LIS_ORI_FLIP
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ static const FRToSI2C::I2C_REG i2c_registers[] = { { CTRL_REG2, 0, 0 }, //Nor
|
|||||||
{ CTRL_REG1, 0x19, 0 } // ODR=12 Hz, Active mode
|
{ CTRL_REG1, 0x19, 0 } // ODR=12 Hz, Active mode
|
||||||
};
|
};
|
||||||
|
|
||||||
void MMA8652FC::initalize() {
|
bool MMA8652FC::initalize() {
|
||||||
FRToSI2C::writeRegistersBulk(MMA8652FC_I2C_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0]));
|
return FRToSI2C::writeRegistersBulk(MMA8652FC_I2C_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0]));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public:
|
|||||||
//Returns true if this accelerometer is detected
|
//Returns true if this accelerometer is detected
|
||||||
static bool detect();
|
static bool detect();
|
||||||
//Init any internal state
|
//Init any internal state
|
||||||
static void initalize();
|
static bool initalize();
|
||||||
static Orientation getOrientation(); // Reads the I2C register and returns the orientation (true == left)
|
static Orientation getOrientation(); // Reads the I2C register and returns the orientation (true == left)
|
||||||
static void getAxisReadings(int16_t &x, int16_t &y, int16_t &z);
|
static void getAxisReadings(int16_t &x, int16_t &y, int16_t &z);
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ static const size_t PIDTaskStackSize = 512 / 4;
|
|||||||
uint32_t PIDTaskBuffer[PIDTaskStackSize];
|
uint32_t PIDTaskBuffer[PIDTaskStackSize];
|
||||||
osStaticThreadDef_t PIDTaskControlBlock;
|
osStaticThreadDef_t PIDTaskControlBlock;
|
||||||
osThreadId MOVTaskHandle;
|
osThreadId MOVTaskHandle;
|
||||||
static const size_t MOVTaskStackSize = 512 / 4;
|
static const size_t MOVTaskStackSize = 1024 / 4;
|
||||||
uint32_t MOVTaskBuffer[MOVTaskStackSize];
|
uint32_t MOVTaskBuffer[MOVTaskStackSize];
|
||||||
osStaticThreadDef_t MOVTaskControlBlock;
|
osStaticThreadDef_t MOVTaskControlBlock;
|
||||||
|
|
||||||
|
|||||||
@@ -603,7 +603,9 @@ uint8_t idleScreenBGF[sizeof(idleScreenBG)];
|
|||||||
/* StartGUITask function */
|
/* StartGUITask function */
|
||||||
void startGUITask(void const *argument __unused) {
|
void startGUITask(void const *argument __unused) {
|
||||||
OLED::initialize(); // start up the LCD
|
OLED::initialize(); // start up the LCD
|
||||||
|
// for (;;) {
|
||||||
|
// osDelay(2000);
|
||||||
|
// }
|
||||||
uint8_t tempWarningState = 0;
|
uint8_t tempWarningState = 0;
|
||||||
bool buttonLockout = false;
|
bool buttonLockout = false;
|
||||||
bool tempOnDisplay = false;
|
bool tempOnDisplay = false;
|
||||||
|
|||||||
@@ -27,21 +27,27 @@ void detectAccelerometerVersion() {
|
|||||||
#ifdef ACCEL_MMA
|
#ifdef ACCEL_MMA
|
||||||
if (MMA8652FC::detect()) {
|
if (MMA8652FC::detect()) {
|
||||||
PCBVersion = 1;
|
PCBVersion = 1;
|
||||||
MMA8652FC::initalize(); // this sets up the I2C registers
|
if(!MMA8652FC::initalize()) {
|
||||||
|
PCBVersion = 99;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef ACCEL_LIS
|
#ifdef ACCEL_LIS
|
||||||
if (LIS2DH12::detect()) {
|
if (LIS2DH12::detect()) {
|
||||||
PCBVersion = 2;
|
PCBVersion = 2;
|
||||||
// Setup the ST Accelerometer
|
// Setup the ST Accelerometer
|
||||||
LIS2DH12::initalize();// startup the accelerometer
|
if(!LIS2DH12::initalize()) {
|
||||||
|
PCBVersion = 99;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef ACCEL_BMA
|
#ifdef ACCEL_BMA
|
||||||
if (BMA223::detect()) {
|
if (BMA223::detect()) {
|
||||||
PCBVersion = 3;
|
PCBVersion = 3;
|
||||||
// Setup the ST Accelerometer
|
// Setup the ST Accelerometer
|
||||||
BMA223::initalize(); // startup the accelerometer
|
if (!BMA223::initalize()) {
|
||||||
|
PCBVersion = 99;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
@@ -76,7 +82,7 @@ inline void readAccelerometer(int16_t& tx, int16_t& ty, int16_t& tz, Orientation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void startMOVTask(void const *argument __unused) {
|
void startMOVTask(void const *argument __unused) {
|
||||||
|
osDelay(10);//Make oled init happen first
|
||||||
postRToSInit();
|
postRToSInit();
|
||||||
OLED::setRotation(systemSettings.OrientationMode & 1);
|
OLED::setRotation(systemSettings.OrientationMode & 1);
|
||||||
detectAccelerometerVersion();
|
detectAccelerometerVersion();
|
||||||
@@ -93,6 +99,17 @@ void startMOVTask(void const *argument __unused) {
|
|||||||
if (systemSettings.sensitivity > 9)
|
if (systemSettings.sensitivity > 9)
|
||||||
systemSettings.sensitivity = 9;
|
systemSettings.sensitivity = 9;
|
||||||
Orientation rotation = ORIENTATION_FLAT;
|
Orientation rotation = ORIENTATION_FLAT;
|
||||||
|
// OLED::setFont(1);
|
||||||
|
// for (;;) {
|
||||||
|
// OLED::clearScreen();
|
||||||
|
// OLED::setCursor(0, 0);
|
||||||
|
// readAccelerometer(tx, ty, tz, rotation);
|
||||||
|
// OLED::printNumber(tx, 5, 0);
|
||||||
|
// OLED::setCursor(0, 8);
|
||||||
|
// OLED::printNumber(xTaskGetTickCount() / 10, 5, 1);
|
||||||
|
// OLED::refresh();
|
||||||
|
// osDelay(50);
|
||||||
|
// }
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int32_t threshold = 1500 + (9 * 200);
|
int32_t threshold = 1500 + (9 * 200);
|
||||||
threshold -= systemSettings.sensitivity * 200; // 200 is the step size
|
threshold -= systemSettings.sensitivity * 200; // 200 is the step size
|
||||||
|
|||||||
Reference in New Issue
Block a user