Update configs for newer pinout

This commit is contained in:
Ben V. Brown
2020-09-17 18:37:57 +10:00
parent 3f6819287d
commit b4c8fc2aab
15 changed files with 668 additions and 644 deletions

View File

@@ -10,20 +10,14 @@
#include "systick.h"
#include <IRQ.h>
//2 second filter (ADC is PID_TIM_HZ Hz)
history<uint16_t, PID_TIM_HZ> rawTempFilter = {{0}, 0, 0};
void resetWatchdog()
{
void resetWatchdog() {
//TODO
}
uint16_t getTipInstantTemperature()
{
uint16_t getTipInstantTemperature() {
uint16_t sum = 0; // 12 bit readings * 8 -> 15 bits
for (int i = 0; i < 4; i++)
{
for (int i = 0; i < 4; i++) {
sum += adc_inserted_data_read(ADC0, i);
sum += adc_inserted_data_read(ADC1, i);
}
@@ -34,113 +28,21 @@ uint16_t getTipInstantTemperature()
// TODO
// Handle callback of the PWM modulator to enable / disable the output PWM
uint16_t getTipRawTemp(uint8_t refresh)
{
if (refresh)
{
uint16_t lastSample = getTipInstantTemperature();
rawTempFilter.update(lastSample);
return lastSample;
}
else
{
return rawTempFilter.average();
}
}
void unstick_I2C()
{
void unstick_I2C() {
// TODO
}
uint8_t getButtonA()
{
return (gpio_input_bit_get(KEY_A_GPIO_Port, KEY_A_Pin) == RESET) ? 1 : 0;
uint8_t getButtonA() {
return (gpio_input_bit_get(KEY_A_GPIO_Port, KEY_A_Pin) == SET) ? 1 : 0;
}
uint8_t getButtonB()
{
return (gpio_input_bit_get(KEY_B_GPIO_Port, KEY_B_Pin) == RESET) ? 1 : 0;
uint8_t getButtonB() {
return (gpio_input_bit_get(KEY_B_GPIO_Port, KEY_B_Pin) == SET) ? 1 : 0;
}
void reboot()
{
void reboot() {
// TODO
for (;;)
{
for (;;) {
}
}
void delay_ms(uint16_t count) { delay_1ms(count); }
uint16_t getHandleTemperature()
{
#ifdef TEMP_NTC
//TS80P uses 100k NTC resistors instead
//NTCG104EF104FT1X from TDK
//For now not doing interpolation
int32_t result = getADC(0);
for (uint32_t i = 0; i < (sizeof(NTCHandleLookup) / (2 * sizeof(uint16_t)));
i++)
{
if (result > NTCHandleLookup[(i * 2) + 0])
{
return NTCHandleLookup[(i * 2) + 1] * 10;
}
}
return 0;
#endif
#ifdef TEMP_TMP36
// We return the current handle temperature in X10 C
// TMP36 in handle, 0.5V offset and then 10mV per deg C (0.75V @ 25C for
// example) STM32 = 4096 count @ 3.3V input -> But We oversample by 32/(2^2) =
// 8 times oversampling Therefore 32768 is the 3.3V input, so 0.1007080078125
// mV per count So we need to subtract an offset of 0.5V to center on 0C
// (4964.8 counts)
//
int32_t result = getADC(0);
result -= 4965; // remove 0.5V offset
// 10mV per C
// 99.29 counts per Deg C above 0C
result *= 100;
result /= 993;
return result;
#endif
}
uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample)
{
// ADC maximum is 32767 == 3.3V at input == 28.05V at VIN
// Therefore we can divide down from there
// Multiplying ADC max by 4 for additional calibration options,
// ideal term is 467
#ifdef MODEL_TS100
#define BATTFILTERDEPTH 32
#else
#define BATTFILTERDEPTH 8
#endif
static uint8_t preFillneeded = 10;
static uint32_t samples[BATTFILTERDEPTH];
static uint8_t index = 0;
if (preFillneeded)
{
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
samples[i] = getADC(1);
preFillneeded--;
}
if (sample)
{
samples[index] = getADC(1);
index = (index + 1) % BATTFILTERDEPTH;
}
uint32_t sum = 0;
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
sum += samples[i];
sum /= BATTFILTERDEPTH;
if (divisor == 0)
{
divisor = 1;
}
return sum * 4 / divisor;
}

View File

@@ -0,0 +1,22 @@
/*
* BSP_PD.c
*
* Created on: 21 Jul 2020
* Author: Ralim
*/
#include "BSP_PD.h"
#include "Model_Config.h"
#ifdef POW_PD
/*
* An array of all of the desired voltages & minimum currents in preferred order
*/
const uint16_t USB_PD_Desired_Levels[] = {
//mV desired input, mA minimum required current
12000, 2400, //12V @ 2.4A
9000, 2000, //9V @ 2A
5000, 100, //5V @ whatever
};
const uint8_t USB_PD_Desired_Levels_Len = 3;
#endif

View File

@@ -14,7 +14,7 @@ extern uint32_t SystemCoreClock;
#define configUSE_TICKLESS_IDLE 0
#define configCPU_CLOCK_HZ ((uint32_t)SystemCoreClock)
#define configRTC_CLOCK_HZ ((uint32_t)TIMER_FREQ)
#define configTICK_RATE_HZ ((TickType_t)100)
#define configTICK_RATE_HZ ((TickType_t)1000)
#define configMAX_PRIORITIES (4) //0 - 3 å…±6等级,idleç¬å<C2AC> 0,Tmr_svcç¬å<C2AC> 3
#define configMINIMAL_STACK_SIZE ((unsigned short)128)
#define configMAX_TASK_NAME_LEN 24

View File

@@ -7,13 +7,13 @@
#include "BSP.h"
#include "Setup.h"
#include <I2C_Wrapper.hpp>
#define I2CUSESDMA
SemaphoreHandle_t FRToSI2C::I2CSemaphore;
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
SemaphoreHandle_t FRToSI2C::I2CSemaphore2;
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer2;
#define FLAG_TIMEOUT 1000
void FRToSI2C::CpltCallback()
{
void FRToSI2C::CpltCallback() {
//TODO
}
@@ -21,31 +21,28 @@ void FRToSI2C::CpltCallback()
*
* @param obj The I2C object
*/
int i2c_start()
{
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)
{
timeout = FLAG_TIMEOUT
;
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET) {
if ((timeout--) == 0) {
return (int)-1;
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;
timeout = FLAG_TIMEOUT
;
while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP) == I2C_CTL0_STOP) {
if ((timeout--) == 0) {
return (int) -1;
}
}
@@ -53,34 +50,30 @@ int i2c_start()
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;
timeout = FLAG_TIMEOUT
;
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) {
if ((timeout--) == 0) {
return (int) -1;
}
}
return (int)0;
return (int) 0;
}
/** Send STOP command
*
* @param obj The I2C object
*/
int i2c_stop()
{
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)
{
while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP)) {
if ((timeout--) == 0) {
return -1;
}
}
@@ -94,32 +87,26 @@ int i2c_stop()
* @param last Acknoledge
* @return The read byte
*/
int i2c_byte_read(int last)
{
int i2c_byte_read(int last) {
int timeout;
if (last)
{
if (last) {
/* disable acknowledge */
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
}
else
{
} 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)
{
while ((i2c_flag_get(I2C0, I2C_FLAG_RBNE)) == RESET) {
if ((timeout--) == 0) {
return -1;
}
}
return (int)i2c_data_receive(I2C0);
return (int) i2c_data_receive(I2C0);
}
/** Write one byte
@@ -128,17 +115,15 @@ int i2c_byte_read(int last)
* @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 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)
{
while (((i2c_flag_get(I2C0, I2C_FLAG_TBE)) == RESET)
|| ((i2c_flag_get(I2C0, I2C_FLAG_BTC)) == RESET)) {
if ((timeout--) == 0) {
return 2;
}
}
@@ -147,8 +132,7 @@ int i2c_byte_write(int data)
}
bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size)
{
uint8_t *pData, uint16_t Size) {
if (!lock())
return false;
@@ -157,18 +141,13 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
/* wait until I2C_FLAG_I2CBSY flag is reset */
timeout = FLAG_TIMEOUT;
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET)
{
if ((timeout--) == 0)
{
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET) {
if ((timeout--) == 0) {
i2c_stop();
unlock();
return false;
}
else
{
if (timeout % 5 == 0)
{
} else {
if (timeout % 5 == 0) {
i2c_stop();
}
}
@@ -177,11 +156,10 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
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)
{
timeout = FLAG_TIMEOUT
;
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) {
if ((timeout--) == 0) {
i2c_stop();
unlock();
return false;
@@ -193,11 +171,9 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
timeout = 0;
/* wait until I2C_FLAG_ADDSEND flag is set */
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
{
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
timeout++;
if (timeout > 100000)
{
if (timeout > 100000) {
i2c_stop();
unlock();
return false;
@@ -205,8 +181,7 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
}
bool no_ack = i2c_flag_get(I2C0, I2C_FLAG_AERR);
no_ack |= i2c_flag_get(I2C0, I2C_FLAG_BERR);
if (no_ack)
{
if (no_ack) {
i2c_stop();
unlock();
return false;
@@ -216,23 +191,21 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
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)
{
if (status == 2 || no_ack) {
i2c_stop();
unlock();
return false;
}
//////////////////////////// //Restart into read
//////////////////////////// //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)
{
timeout = FLAG_TIMEOUT
;
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) {
if ((timeout--) == 0) {
i2c_stop();
unlock();
return false;
@@ -244,11 +217,9 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
timeout = 0;
/* wait until I2C_FLAG_ADDSEND flag is set */
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
{
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
timeout++;
if (timeout > 100000)
{
if (timeout > 100000) {
i2c_stop();
unlock();
return false;
@@ -258,15 +229,13 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
/* clear ADDSEND */
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
no_ack = i2c_flag_get(I2C0, I2C_FLAG_AERR);
if (no_ack)
{
if (no_ack) {
i2c_stop();
unlock();
return false;
}
for (count = 0; count < Size; count++)
{
pData[count] = i2c_byte_read(count == (uint32_t)(Size - 1));
for (count = 0; count < Size; count++) {
pData[count] = i2c_byte_read(count == (Size - 1));
}
/* if not sequential write, then send stop */
@@ -275,40 +244,33 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
unlock();
return true;
}
void FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data)
{
Mem_Write(address, reg, &data, 1);
bool FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) {
return Mem_Write(address, reg, &data, 1);
}
uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg)
{
uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
uint8_t temp = 0;
Mem_Read(add, reg, &temp, 1);
return temp;
}
void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size)
{
bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size) {
if (!lock())
return;
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)
{
timeout = FLAG_TIMEOUT
;
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET) {
if ((timeout--) == 0) {
i2c_stop();
unlock();
return;
}
else
{
if (timeout % 5 == 0)
{
return false;
} else {
if (timeout % 5 == 0) {
i2c_stop();
}
}
@@ -317,14 +279,13 @@ void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
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)
{
timeout = FLAG_TIMEOUT
;
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) {
if ((timeout--) == 0) {
i2c_stop();
unlock();
return;
return false;
}
}
@@ -333,28 +294,24 @@ void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
timeout = 0;
/* wait until I2C_FLAG_ADDSEND flag is set */
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
{
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
timeout++;
if (timeout > 100000)
{
if (timeout > 100000) {
i2c_stop();
unlock();
return;
return false;
}
}
/* clear ADDSEND */
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
int status = i2c_byte_write(MemAddress);
for (count = 0; count < Size; count++)
{
for (count = 0; count < Size; count++) {
status = i2c_byte_write(pData[count]);
if (status != 1)
{
if (status != 1) {
i2c_stop();
unlock();
return;
return false;
}
}
@@ -362,29 +319,24 @@ void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
i2c_stop();
unlock();
return true;
}
void 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;
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)
{
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET) {
if ((timeout--) == 0) {
i2c_stop();
unlock();
return;
}
else
{
if (timeout % 5 == 0)
{
return false;
} else {
if (timeout % 5 == 0) {
i2c_stop();
}
}
@@ -393,14 +345,13 @@ void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size)
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)
{
timeout = FLAG_TIMEOUT
;
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) {
if ((timeout--) == 0) {
i2c_stop();
unlock();
return;
return false;
}
}
@@ -409,28 +360,24 @@ void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size)
timeout = 0;
/* wait until I2C_FLAG_ADDSEND flag is set */
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
{
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
timeout++;
if (timeout > 100000)
{
if (timeout > 100000) {
i2c_stop();
unlock();
return;
return false;
}
}
/* clear ADDSEND */
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
for (count = 0; count < Size; count++)
{
for (count = 0; count < Size; count++) {
int status = i2c_byte_write(pData[count]);
if (status != 1)
{
if (status != 1) {
i2c_stop();
unlock();
return;
return false;
}
}
@@ -438,10 +385,10 @@ void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size)
i2c_stop();
unlock();
return true;
}
bool FRToSI2C::probe(uint16_t DevAddress)
{
bool FRToSI2C::probe(uint16_t DevAddress) {
if (!lock())
return false;
i2c_start();
@@ -449,16 +396,14 @@ bool FRToSI2C::probe(uint16_t DevAddress)
i2c_master_addressing(I2C0, DevAddress, I2C_TRANSMITTER);
/* wait until ADDSEND bit is set */
int timeout = FLAG_TIMEOUT;
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
{
if (i2c_flag_get(I2C0, I2C_FLAG_AERR) || i2c_flag_get(I2C0, I2C_FLAG_BERR))
{
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
if (i2c_flag_get(I2C0, I2C_FLAG_AERR)
|| i2c_flag_get(I2C0, I2C_FLAG_BERR)) {
i2c_stop();
unlock();
return false;
}
if (timeout-- == 0)
{
if (timeout-- == 0) {
i2c_stop();
unlock();
return false;
@@ -480,21 +425,29 @@ bool FRToSI2C::probe(uint16_t DevAddress)
return !no_ack;
}
void FRToSI2C::I2C_Unstick()
{
void FRToSI2C::I2C_Unstick() {
unstick_I2C();
}
bool FRToSI2C::lock()
{
bool FRToSI2C::lock() {
if (I2CSemaphore == nullptr)
return true;
return xSemaphoreTake(I2CSemaphore, 1000) == pdTRUE;
return xSemaphoreTake(I2CSemaphore,1000) == pdTRUE;
}
void FRToSI2C::unlock()
{
void FRToSI2C::unlock() {
if (I2CSemaphore == nullptr)
return;
xSemaphoreGive(I2CSemaphore);
}
bool FRToSI2C::lock2() {
if (I2CSemaphore2 == nullptr)
return true;
return xSemaphoreTake(I2CSemaphore2,1000) == pdTRUE;
}
void FRToSI2C::unlock2() {
if (I2CSemaphore2 == nullptr)
return;
xSemaphoreGive(I2CSemaphore2);
}

View File

@@ -1,27 +1,24 @@
/*
* Model_Config.h
*
* Created on: 25 Jul 2020
* Author: Ralim
*/
#ifndef BSP_MINIWARE_MODEL_CONFIG_H_
#define BSP_MINIWARE_MODEL_CONFIG_H_
/*
* Lookup for mapping features <-> Models
*/
#if defined(MODEL_Pinecil) > 1
#error "Multiple models defined!"
#elif defined(MODEL_Pinecil) == 0
#error "No model defined!"
#endif
#ifdef MODEL_Pinecil
#define ACCEL_LIS
#define TEMP_TMP36
#define POW_QC
// #define POW_PD
#endif
#endif /* BSP_MINIWARE_MODEL_CONFIG_H_ */
/*
* Model_Config.h
*
* Created on: 25 Jul 2020
* Author: Ralim
*/
#ifndef BSP_MINIWARE_MODEL_CONFIG_H_
#define BSP_MINIWARE_MODEL_CONFIG_H_
/*
* Lookup for mapping features <-> Models
*/
#if defined(MODEL_Pinecil) == 0
#error "No model defined!"
#endif
#ifdef MODEL_Pinecil
#define POW_PD
#define POW_QC
#define TEMP_TMP36
#endif
#endif /* BSP_MINIWARE_MODEL_CONFIG_H_ */

View File

@@ -1,4 +1,3 @@
#include "FreeRTOSConfig.h"
#include "FreeRTOS.h"
#include "task.h"
#include "portmacro.h"
@@ -7,32 +6,36 @@
#include "riscv_encoding.h"
#include "n200_timer.h"
#include "n200_eclic.h"
/* Standard Includes */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
/* Each task maintains its own interrupt status in the critical nesting variable. */
UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
#if USER_MODE_TASKS
#ifdef __riscv_flen
unsigned long MSTATUS_INIT = (MSTATUS_MPIE | (0x1 << 13));
unsigned long MSTATUS_INIT = (MSTATUS_MPIE | (0x1 << 13));
#else
unsigned long MSTATUS_INIT = (MSTATUS_MPIE);
unsigned long MSTATUS_INIT = (MSTATUS_MPIE);
#endif
#else
#ifdef __riscv_flen
unsigned long MSTATUS_INIT = (MSTATUS_MPP | MSTATUS_MPIE | (0x1 << 13));
unsigned long MSTATUS_INIT = (MSTATUS_MPP | MSTATUS_MPIE | (0x1 << 13));
#else
unsigned long MSTATUS_INIT = (MSTATUS_MPP | MSTATUS_MPIE);
unsigned long MSTATUS_INIT = (MSTATUS_MPP | MSTATUS_MPIE);
#endif
#endif
/*
* Used to catch tasks that attempt to return from their implementing function.
*/
static void prvTaskExitError(void);
static void prvTaskExitError( void );
/**
* @brief System Call Trap
@@ -44,51 +47,52 @@ static void prvTaskExitError(void);
*/
unsigned long ulSynchTrap(unsigned long mcause, unsigned long sp, unsigned long arg1)
{
switch (mcause & 0X00000fff)
switch(mcause&0X00000fff)
{
//on User and Machine ECALL, handler the request
case 8:
case 11:
{
if (arg1 == IRQ_DISABLE)
//on User and Machine ECALL, handler the request
case 8:
case 11:
{
//zero out mstatus.mpie
clear_csr(mstatus, MSTATUS_MPIE);
if(arg1==IRQ_DISABLE)
{
//zero out mstatus.mpie
clear_csr(mstatus,MSTATUS_MPIE);
}
else if(arg1==IRQ_ENABLE)
{
//set mstatus.mpie
set_csr(mstatus,MSTATUS_MPIE);
}
else if(arg1==PORT_YIELD)
{
//always yield from machine mode
//fix up mepc on sync trap
unsigned long epc = read_csr(mepc);
vPortYield_from_ulSynchTrap(sp,epc+4);
}
else if(arg1==PORT_YIELD_TO_RA)
{
vPortYield_from_ulSynchTrap(sp,(*(unsigned long*)(sp+1*sizeof(sp))));
}
break;
}
else if (arg1 == IRQ_ENABLE)
default:
{
//set mstatus.mpie
set_csr(mstatus, MSTATUS_MPIE);
/* 异常处理 */
extern uintptr_t handle_trap(uintptr_t mcause, uintptr_t sp);
handle_trap(mcause,sp);
}
else if (arg1 == PORT_YIELD)
{
//always yield from machine mode
//fix up mepc on sync trap
unsigned long epc = read_csr(mepc);
vPortYield_from_ulSynchTrap(sp, epc + 4);
}
else if (arg1 == PORT_YIELD_TO_RA)
{
vPortYield_from_ulSynchTrap(sp, (*(unsigned long *)(sp + 1 * sizeof(sp))));
}
break;
}
default:
{
/* 异常处理 */
extern uintptr_t handle_trap(uintptr_t mcause, uintptr_t sp);
handle_trap(mcause, sp);
}
}
//fix mepc and return
unsigned long epc = read_csr(mepc);
write_csr(mepc, epc + 4);
write_csr(mepc,epc+4);
return sp;
}
/*-----------------------------------------------------------*/
/**
* @brief 设置触发软中断
* @note 目的是在软中断内进行任务上下文切换
@@ -96,22 +100,24 @@ unsigned long ulSynchTrap(unsigned long mcause, unsigned long sp, unsigned long
*/
void vPortSetMSIPInt(void)
{
*(volatile uint8_t *)(TIMER_CTRL_ADDR + TIMER_MSIP) |= 0x01;
*(volatile uint8_t *) (TIMER_CTRL_ADDR + TIMER_MSIP) |=0x01;
__asm volatile("fence");
__asm volatile("fence.i");
}
/*-----------------------------------------------------------*/
/**
* @brief 清除软中断
*
*/
void vPortClearMSIPInt(void)
{
*(volatile uint8_t *)(TIMER_CTRL_ADDR + TIMER_MSIP) &= ~0x01;
*(volatile uint8_t *) (TIMER_CTRL_ADDR + TIMER_MSIP) &= ~0x01;
}
/*-----------------------------------------------------------*/
/**
* @brief 执行任务上下文切换,在portasm.S中被调用
*
@@ -119,22 +125,23 @@ void vPortClearMSIPInt(void)
* @param arg1
* @return unsigned long sp地址
*/
unsigned long taskswitch(unsigned long sp, unsigned long arg1)
unsigned long taskswitch( unsigned long sp, unsigned long arg1)
{
//always yield from machine mode
//fix up mepc on
unsigned long epc = read_csr(mepc);
vPortYield(sp, epc); //never returns
vPortYield(sp,epc); //never returns
return sp;
}
/*-----------------------------------------------------------*/
/**
* @brief 调研freertos内建函数vTaskSwitchContext,在portasm.S中被调用
*
*/
void vDoTaskSwitchContext(void)
void vDoTaskSwitchContext( void )
{
portDISABLE_INTERRUPTS();
vTaskSwitchContext();
@@ -142,42 +149,45 @@ void vDoTaskSwitchContext(void)
}
/*-----------------------------------------------------------*/
/**
* @brief 进入临界段
*
*/
void vPortEnterCritical(void)
void vPortEnterCritical( void )
{
#if USER_MODE_TASKS
ECALL(IRQ_DISABLE);
#else
portDISABLE_INTERRUPTS();
#endif
#if USER_MODE_TASKS
ECALL(IRQ_DISABLE);
#else
portDISABLE_INTERRUPTS();
#endif
uxCriticalNesting++;
}
/*-----------------------------------------------------------*/
/**
* @brief 退出临界段
*
*/
void vPortExitCritical(void)
void vPortExitCritical( void )
{
configASSERT(uxCriticalNesting);
configASSERT( uxCriticalNesting );
uxCriticalNesting--;
if (uxCriticalNesting == 0)
if( uxCriticalNesting == 0 )
{
#if USER_MODE_TASKS
ECALL(IRQ_ENABLE);
#else
portENABLE_INTERRUPTS();
#endif
#if USER_MODE_TASKS
ECALL(IRQ_ENABLE);
#else
portENABLE_INTERRUPTS();
#endif
}
return;
}
/*-----------------------------------------------------------*/
/**
* @brief Clear current interrupt mask and set given mask
*
@@ -185,10 +195,11 @@ void vPortExitCritical(void)
*/
void vPortClearInterruptMask(int int_mask)
{
eclic_set_mth(int_mask);
eclic_set_mth (int_mask);
}
/*-----------------------------------------------------------*/
/**
* @brief Set interrupt mask and return current interrupt enable register
*
@@ -196,14 +207,15 @@ void vPortClearInterruptMask(int int_mask)
*/
int xPortSetInterruptMask(void)
{
int int_mask = 0;
int_mask = eclic_get_mth();
int int_mask=0;
int_mask=eclic_get_mth();
portDISABLE_INTERRUPTS();
return int_mask;
}
/*-----------------------------------------------------------*/
/**
* @brief 初始化任务栈帧
*
@@ -212,30 +224,30 @@ int xPortSetInterruptMask(void)
* @param pvParameters 任务参数
* @return StackType_t* 完成初始化后的栈顶
*/
StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters)
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
/* Simulate the stack frame as it would be created by a context switch
interrupt. */
#ifdef __riscv_flen
pxTopOfStack -= 32; /* 浮点寄存器 */
pxTopOfStack -= 32; /* 浮点寄存器 */
#endif
pxTopOfStack--;
*pxTopOfStack = 0xb8000000; /* CSR_MCAUSE */
*pxTopOfStack = 0xb8000000; /* CSR_MCAUSE */
pxTopOfStack--;
*pxTopOfStack = 0x40; /* CSR_SUBM */
*pxTopOfStack = 0x40; /* CSR_SUBM */
pxTopOfStack--;
*pxTopOfStack = (portSTACK_TYPE)pxCode; /* Start address */
*pxTopOfStack = (portSTACK_TYPE)pxCode; /* Start address */
pxTopOfStack--;
*pxTopOfStack = MSTATUS_INIT; /* CSR_MSTATUS */
*pxTopOfStack = MSTATUS_INIT; /* CSR_MSTATUS */
pxTopOfStack -= 22;
*pxTopOfStack = (portSTACK_TYPE)pvParameters; /* Register a0 */
*pxTopOfStack = (portSTACK_TYPE)pvParameters; /* Register a0 */
pxTopOfStack -= 9;
pxTopOfStack -=9;
*pxTopOfStack = (portSTACK_TYPE)prvTaskExitError; /* Register ra */
pxTopOfStack--;
@@ -243,24 +255,25 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC
}
/*-----------------------------------------------------------*/
/**
* @brief 任务退出函数
*
*/
void prvTaskExitError(void)
void prvTaskExitError( void )
{
/* A function that implements a task must not exit or attempt to return to
its caller as there is nothing to return to. If a task wants to exit it
should instead call vTaskDelete( NULL ).
Artificially force an assert() to be triggered if configASSERT() is
defined, then stop here so application writers can catch the error. */
configASSERT(uxCriticalNesting == ~0UL);
configASSERT( uxCriticalNesting == ~0UL );
portDISABLE_INTERRUPTS();
for (;;)
;
for( ;; );
}
/*-----------------------------------------------------------*/
/**
* @brief tick中断
* @note 由于该中断配置为向量模式则中断到来会调用portasm.S的MTIME_HANDLER,进行栈帧保存之后该函数会调用vPortSysTickHandler
@@ -268,38 +281,39 @@ void prvTaskExitError(void)
*/
void vPortSysTickHandler(void)
{
volatile uint64_t *mtime = (uint64_t *)(TIMER_CTRL_ADDR + TIMER_MTIME);
volatile uint64_t *mtimecmp = (uint64_t *)(TIMER_CTRL_ADDR + TIMER_MTIMECMP);
volatile uint64_t * mtime = (uint64_t*) (TIMER_CTRL_ADDR + TIMER_MTIME);
volatile uint64_t * mtimecmp = (uint64_t*) (TIMER_CTRL_ADDR + TIMER_MTIMECMP);
UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
#if CONFIG_SYSTEMVIEW_EN
#if CONFIG_SYSTEMVIEW_EN
traceISR_ENTER();
#endif
#endif
uint64_t now = *mtime;
now += (configRTC_CLOCK_HZ / configTICK_RATE_HZ);
*mtimecmp = now;
/* 调用freertos的tick增加接口 */
if (xTaskIncrementTick() != pdFALSE)
if( xTaskIncrementTick() != pdFALSE )
{
#if CONFIG_SYSTEMVIEW_EN
#if CONFIG_SYSTEMVIEW_EN
traceISR_EXIT_TO_SCHEDULER();
#endif
#endif
portYIELD();
}
#if CONFIG_SYSTEMVIEW_EN
#if CONFIG_SYSTEMVIEW_EN
else
{
traceISR_EXIT();
}
#endif
#endif
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
}
/*-----------------------------------------------------------*/
/**
* @brief 初始化tick
*
@@ -307,20 +321,21 @@ void vPortSysTickHandler(void)
void vPortSetupTimer(void)
{
/* 内核timer定时器使用64位的计数器来实现 */
volatile uint64_t *mtime = (uint64_t *)(TIMER_CTRL_ADDR + TIMER_MTIME);
volatile uint64_t *mtimecmp = (uint64_t *)(TIMER_CTRL_ADDR + TIMER_MTIMECMP);
volatile uint64_t * mtime = (uint64_t*) (TIMER_CTRL_ADDR + TIMER_MTIME);
volatile uint64_t * mtimecmp = (uint64_t*) (TIMER_CTRL_ADDR + TIMER_MTIMECMP);
portENTER_CRITICAL();
uint64_t now = *mtime;
now += (configRTC_CLOCK_HZ / configTICK_RATE_HZ);
*mtimecmp = now;
uint64_t now = *mtime;
now += (configRTC_CLOCK_HZ / configTICK_RATE_HZ);
*mtimecmp = now;
portEXIT_CRITICAL();
eclic_set_vmode(CLIC_INT_TMR);
eclic_irq_enable(CLIC_INT_TMR, configKERNEL_INTERRUPT_PRIORITY >> configPRIO_BITS, 0);
eclic_irq_enable(CLIC_INT_TMR,configKERNEL_INTERRUPT_PRIORITY>>configPRIO_BITS,0);
}
/*-----------------------------------------------------------*/
/**
* @brief 初始化软中断
*
@@ -328,10 +343,11 @@ void vPortSetupTimer(void)
void vPortSetupMSIP(void)
{
eclic_set_vmode(CLIC_INT_SFT);
eclic_irq_enable(CLIC_INT_SFT, configKERNEL_INTERRUPT_PRIORITY >> configPRIO_BITS, 0);
eclic_irq_enable(CLIC_INT_SFT,configKERNEL_INTERRUPT_PRIORITY>>configPRIO_BITS,0);
}
/*-----------------------------------------------------------*/
/**
* @brief 调度启动前的初始化准备
*

View File

@@ -1,13 +1,14 @@
#ifndef PINE_PORTMACRO_H
#define PINE_PORTMACRO_H
#ifndef PORTMACRO_H
#define PORTMACRO_H
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
#include "riscv_encoding.h"
/*-----------------------------------------------------------
* Port specific definitions.
*
@@ -19,128 +20,123 @@ extern "C"
*/
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if (configUSE_16_BIT_TICKS == 1)
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY (TickType_t)0xffff
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY (TickType_t)0xffffffffUL
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH (-1)
#define portTICK_PERIOD_MS ((TickType_t)1000 / configTICK_RATE_HZ)
#define portBYTE_ALIGNMENT 8
/*-----------------------------------------------------------*/
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
/*-----------------------------------------------------------*/
/* Architecture specifics. */
extern void vPortYield(unsigned long,unsigned long);
extern void vPortYield_from_ulSynchTrap(unsigned long,unsigned long);
extern int xPortSetInterruptMask(void);
extern void vPortClearInterruptMask( int uxSavedStatusValue );
/* Architecture specifics. */
extern void vPortYield(unsigned long, unsigned long);
extern void vPortYield_from_ulSynchTrap(unsigned long, unsigned long);
extern int xPortSetInterruptMask(void);
extern void vPortClearInterruptMask(int uxSavedStatusValue);
/*-----------------------------------------------------------*/
/*System Calls */
/*-----------------------------------------------------------*/
//ecall macro used to store argument in a3
#define ECALL(arg) ({ \
register uintptr_t a2 asm("a2") = (uintptr_t)(arg); \
asm volatile("ecall" \
: "+r"(a2) \
: \
: "memory"); \
a2; \
#define ECALL(arg) ({ \
register uintptr_t a2 asm ("a2") = (uintptr_t)(arg); \
asm volatile ("ecall" \
: "+r" (a2) \
: \
: "memory"); \
a2; \
})
extern void vPortSetMSIPInt(void);
extern void vPortSetMSIPInt(void);
#define port_MSIPSET_BIT vPortSetMSIPInt()
#define IRQ_DISABLE 20
#define IRQ_ENABLE 30
#define PORT_YIELD 40
#define PORT_YIELD_TO_RA 50
#define IRQ_DISABLE 20
#define IRQ_ENABLE 30
#define PORT_YIELD 40
#define PORT_YIELD_TO_RA 50
/*-----------------------------------------------------------*/
/* Scheduler utilities. */
/* the return after the ECALL is VERY important */
//#define portYIELD() ECALL(PORT_YIELD);
#define portYIELD() port_MSIPSET_BIT;
#ifdef CONFIG_SYSTEMVIEW_EN
#define portEND_SWITCHING_ISR(xSwitchRequired) \
{ \
if (xSwitchRequired != pdFALSE) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
}
#if CONFIG_SYSTEMVIEW_EN
#define portEND_SWITCHING_ISR(xSwitchRequired) { if( xSwitchRequired != pdFALSE) { traceISR_EXIT_TO_SCHEDULER(); portYIELD(); } else {traceISR_EXIT(); } }
#else
#define portEND_SWITCHING_ISR(xSwitchRequired) \
if (xSwitchRequired != pdFALSE) \
portYIELD()
#define portEND_SWITCHING_ISR(xSwitchRequired) if( xSwitchRequired != pdFALSE) portYIELD()
#endif
#define portYIELD_FROM_ISR(x) portEND_SWITCHING_ISR(x)
#define portYIELD_FROM_ISR(x) portEND_SWITCHING_ISR(x)
/* Critical section management. */
extern void vPortEnterCritical(void);
extern void vPortExitCritical(void);
extern void eclic_set_mth(uint8_t mth);
#define portDISABLE_INTERRUPTS() \
{ \
eclic_set_mth((configMAX_SYSCALL_INTERRUPT_PRIORITY) | 0x1f); \
__asm volatile("fence"); \
__asm volatile("fence.i"); \
}
#define portENABLE_INTERRUPTS() eclic_set_mth(0)
#define portSET_INTERRUPT_MASK_FROM_ISR() xPortSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedStatusValue) vPortClearInterruptMask(uxSavedStatusValue)
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/* Critical section management. */
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
extern void eclic_set_mth (uint8_t mth);
#define portDISABLE_INTERRUPTS() \
{ \
eclic_set_mth((configMAX_SYSCALL_INTERRUPT_PRIORITY)|0x1f); \
__asm volatile("fence"); \
__asm volatile("fence.i"); \
}
#define portENABLE_INTERRUPTS() eclic_set_mth(0)
#define portSET_INTERRUPT_MASK_FROM_ISR() xPortSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) vPortClearInterruptMask( uxSavedStatusValue )
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. These are
not necessary for to use this port. They are defined so the common demo files
(which build with all the ports) will build. */
#define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void *pvParameters)
#define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters)
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/*-----------------------------------------------------------*/
/* Tickless idle/low power functionality. */
#ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime);
#define portSUPPRESS_TICKS_AND_SLEEP(xExpectedIdleTime) vPortSuppressTicksAndSleep(xExpectedIdleTime)
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
#define portINLINE __inline
#define portINLINE __inline
#ifndef portFORCE_INLINE
#define portFORCE_INLINE inline __attribute__((always_inline))
#define portFORCE_INLINE inline __attribute__(( always_inline))
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View File

@@ -7,17 +7,17 @@
| 17 | PB2 | BOOT2 | Pulldown |
| 32 | | IMU INT 1 | N/A |
| 30 | | IMU INT 2 | N/A |
| 14 | PA7 | Handle Temp | ADC Input 7 |
| 15 | PB0 | Tip Temp | ADC Input 8 |
| 13 | PA6 | B Button | Active Low |
| 21 | PA9 | A Button | Active Low |
| 23 | PA11 | USB D- | - |
| 24 | PA12 | USB D+ | - |
| 31 | PB4 | Tip PWM Out | TIMER2_CH0 |
| 16 | PB1 | Input DC V Sense | ADC Input 9 |
| 20 | PA8 | OLED Reset | |
| 34 | PB7 | SDA | I2C0_SDA |
| 33 | PB6 | SCL | I2C0_SCL |
| | PA4 | Handle Temp | ADC Input ? |
| | PA1 | Tip Temp | ADC Input ? |
| | PB1 | B Button | Active High |
| | PB0 | A Button | Active High |
| | PA11 | USB D- | - |
| | PA12 | USB D+ | - |
| | PA6 | Tip PWM Out | - |
| | PA0 | Input DC V Sense | ADC Input ? |
| | PA9 | OLED Reset | |
| | PB7 | SDA | I2C0_SDA |
| | PB6 | SCL | I2C0_SCL |
## ADC Configuration

View File

@@ -9,27 +9,27 @@
#define BSP_MINIWARE_PINS_H_
#include "Vendor/Lib/gd32vf103_gpio.h"
//TODO
#define KEY_B_Pin BIT(6)
#define KEY_B_GPIO_Port GPIOA
#define TMP36_INPUT_Pin BIT(7)
#define KEY_B_Pin BIT(1)
#define KEY_B_GPIO_Port GPIOB
#define TMP36_INPUT_Pin BIT(4)
#define TMP36_INPUT_GPIO_Port GPIOA
#define TMP36_ADC1_CHANNEL ADC_CHANNEL_7
#define TMP36_ADC2_CHANNEL ADC_CHANNEL_7
#define TIP_TEMP_Pin BIT(0)
#define TIP_TEMP_GPIO_Port GPIOB
#define TIP_TEMP_ADC1_CHANNEL ADC_CHANNEL_8
#define TIP_TEMP_ADC2_CHANNEL ADC_CHANNEL_8
#define TMP36_ADC1_CHANNEL ADC_CHANNEL_4
#define TMP36_ADC2_CHANNEL ADC_CHANNEL_4
#define TIP_TEMP_Pin BIT(1)
#define TIP_TEMP_GPIO_Port GPIOA
#define TIP_TEMP_ADC1_CHANNEL ADC_CHANNEL_1
#define TIP_TEMP_ADC2_CHANNEL ADC_CHANNEL_1
#define VIN_Pin BIT(1)
#define VIN_GPIO_Port GPIOB
#define VIN_ADC1_CHANNEL ADC_CHANNEL_9
#define VIN_ADC2_CHANNEL ADC_CHANNEL_9
#define OLED_RESET_Pin BIT(8)
#define VIN_Pin BIT(0)
#define VIN_GPIO_Port GPIOA
#define VIN_ADC1_CHANNEL ADC_CHANNEL_0
#define VIN_ADC2_CHANNEL ADC_CHANNEL_0
#define OLED_RESET_Pin BIT(9)
#define OLED_RESET_GPIO_Port GPIOA
#define KEY_A_Pin BIT(9)
#define KEY_A_GPIO_Port GPIOA
#define PWM_Out_Pin BIT(4)
#define PWM_Out_GPIO_Port GPIOB
#define KEY_A_Pin BIT(0)
#define KEY_A_GPIO_Port GPIOB
#define PWM_Out_Pin BIT(6)
#define PWM_Out_GPIO_Port GPIOA
#define SCL_Pin BIT(6)
#define SCL_GPIO_Port GPIOB
#define SDA_Pin BIT(7)

View File

@@ -9,32 +9,28 @@
#include "int_n.h"
bool FUSB302_present = false;
void power_check()
{
void power_check() {
#ifdef POW_PD
if (FUSB302_present)
{
//Cant start QC until either PD works or fails
if (PolicyEngine::setupCompleteOrTimedOut() == false)
{
return;
}
if (PolicyEngine::pdHasNegotiated())
{
return;
}
}
if (FUSB302_present) {
//Cant start QC until either PD works or fails
if (PolicyEngine::setupCompleteOrTimedOut() == false) {
return;
}
if (PolicyEngine::pdHasNegotiated()) {
return;
}
}
#endif
#ifdef POW_QC
QC_resync();
QC_resync();
#endif
}
uint8_t usb_pd_detect()
{
uint8_t usb_pd_detect() {
#ifdef POW_PD
FUSB302_present = fusb302_detect();
FUSB302_present = fusb302_detect();
return FUSB302_present;
return FUSB302_present;
#endif
return false;
return false;
}

View File

@@ -55,8 +55,8 @@ void setup_gpio() {
//Alternate function clock enable
rcu_periph_clock_enable(RCU_AF);
//Buttons as input
gpio_init(KEY_A_GPIO_Port, GPIO_MODE_IPU, GPIO_OSPEED_2MHZ, KEY_A_Pin);
gpio_init(KEY_B_GPIO_Port, GPIO_MODE_IPU, GPIO_OSPEED_2MHZ, KEY_B_Pin);
gpio_init(KEY_A_GPIO_Port, GPIO_MODE_IPD, GPIO_OSPEED_2MHZ, KEY_A_Pin);
gpio_init(KEY_B_GPIO_Port, GPIO_MODE_IPD, GPIO_OSPEED_2MHZ, KEY_B_Pin);
//OLED reset as output
gpio_init(OLED_RESET_GPIO_Port, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ,
OLED_RESET_Pin);
@@ -73,7 +73,7 @@ void setup_gpio() {
TIP_TEMP_Pin);
gpio_init(VIN_GPIO_Port, GPIO_MODE_AIN, GPIO_OSPEED_2MHZ, VIN_Pin);
//Timer 2 remap to move timer 2 ch0 to pin PB4
gpio_pin_remap_config(GPIO_TIMER2_PARTIAL_REMAP, ENABLE);
// gpio_pin_remap_config(GPIO_TIMER2_PARTIAL_REMAP, ENABLE);
//Remap PB4 away from JTAG NJRST
gpio_pin_remap_config(GPIO_SWJ_NONJTRST_REMAP, ENABLE);
//TODO - rest of pins as floating
@@ -112,7 +112,7 @@ void setup_i2c() {
/* enable I2C0 clock */
rcu_periph_clock_enable(RCU_I2C0);
//Setup I20 at 100kHz with DMA?
i2c_clock_config(I2C0, 400 * 1000, I2C_DTCY_16_9);
i2c_clock_config(I2C0, 100 * 1000, I2C_DTCY_16_9);
i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x00);
i2c_enable(I2C0);
/* enable acknowledge */

View File

@@ -0,0 +1,176 @@
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
/* Run in FLASH */
flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 128k
ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 32K
/* Run in RAM */
/* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 24k
ram (wxa!ri) : ORIGIN = 0x20006000, LENGTH = 8K
*/
}
SECTIONS
{
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
.init :
{
KEEP (*(SORT_NONE(.init)))
} >flash AT>flash
.ilalign :
{
. = ALIGN(4);
PROVIDE( _ilm_lma = . );
} >flash AT>flash
.ialign :
{
PROVIDE( _ilm = . );
} >flash AT>flash
.text :
{
*(.rodata .rodata.*)
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >flash AT>flash
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >flash AT>flash
. = ALIGN(4);
PROVIDE (__etext = .);
PROVIDE (_etext = .);/*0x80022c8*/
PROVIDE (etext = .);/*0x80022c8*/
PROVIDE( _eilm = . );
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >flash AT>flash
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >flash AT>flash
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >flash AT>flash
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >flash AT>flash
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >flash AT>flash
. = ALIGN(4);
PROVIDE( _eilm = . );
.lalign :
{
. = ALIGN(4);
PROVIDE( _data_lma = . );
} >flash AT>flash
.dalign :
{
. = ALIGN(4);
PROVIDE( _data = . );
} >ram AT>flash
.data :
{
*(.rdata)
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800);
*(.sdata .sdata.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} >ram AT>flash
. = ALIGN(4);
PROVIDE( _edata = . );
PROVIDE( edata = . );
PROVIDE( _fbss = . ); /*0X200052A0 0X200002A0*/
PROVIDE( __bss_start = . );
.bss :
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >ram AT>ram
. = ALIGN(8);
PROVIDE( _end = . ); /*0X2000,0340*/
PROVIDE( end = . );
PROVIDE( heap_start = . );
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
{
PROVIDE( heap_end = . );
. = __stack_size;
PROVIDE( _sp = . );
} >ram AT>ram
}

View File

@@ -29,11 +29,9 @@
*
* Returns the value read from addr.
*/
static uint8_t fusb_read_byte(uint8_t addr)
{
static uint8_t fusb_read_byte(uint8_t addr) {
uint8_t data[1];
if (!FRToSI2C::Mem_Read(FUSB302B_ADDR, addr, (uint8_t *)data, 1))
{
if (!FRToSI2C::Mem_Read(FUSB302B_ADDR, addr, (uint8_t*) data, 1)) {
return 0;
}
return data[0];
@@ -47,8 +45,7 @@ static uint8_t fusb_read_byte(uint8_t addr)
* size: The number of bytes to read
* buf: The buffer into which data will be read
*/
static bool fusb_read_buf(uint8_t addr, uint8_t size, uint8_t *buf)
{
static bool fusb_read_buf(uint8_t addr, uint8_t size, uint8_t *buf) {
return FRToSI2C::Mem_Read(FUSB302B_ADDR, addr, buf, size);
}
@@ -59,9 +56,9 @@ static bool fusb_read_buf(uint8_t addr, uint8_t size, uint8_t *buf)
* addr: The memory address to which we will write
* byte: The value to write
*/
static bool fusb_write_byte(uint8_t addr, uint8_t byte)
{
return FRToSI2C::Mem_Write(FUSB302B_ADDR, addr, (uint8_t *)&byte, 1);
static bool fusb_write_byte(uint8_t addr, uint8_t byte) {
FRToSI2C::Mem_Write(FUSB302B_ADDR, addr, (uint8_t*) &byte, 1);
return true;
}
/*
@@ -72,29 +69,27 @@ static bool fusb_write_byte(uint8_t addr, uint8_t byte)
* size: The number of bytes to write
* buf: The buffer to write
*/
static bool fusb_write_buf(uint8_t addr, uint8_t size, const uint8_t *buf)
{
return FRToSI2C::Mem_Write(FUSB302B_ADDR, addr, buf, size);
static bool fusb_write_buf(uint8_t addr, uint8_t size, const uint8_t *buf) {
FRToSI2C::Mem_Write(FUSB302B_ADDR, addr, (uint8_t*)buf, size);
return true; //TODO
}
void fusb_send_message(const union pd_msg *msg)
{
if (!FRToSI2C::lock2())
{
void fusb_send_message(const union pd_msg *msg) {
if (!FRToSI2C::lock2()) {
return;
}
/* Token sequences for the FUSB302B */
static uint8_t sop_seq[5] = {
FUSB_FIFO_TX_SOP1,
FUSB_FIFO_TX_SOP1,
FUSB_FIFO_TX_SOP1,
FUSB_FIFO_TX_SOP2,
FUSB_FIFO_TX_PACKSYM};
FUSB_FIFO_TX_SOP1,
FUSB_FIFO_TX_SOP1,
FUSB_FIFO_TX_SOP1,
FUSB_FIFO_TX_SOP2,
FUSB_FIFO_TX_PACKSYM };
static const uint8_t eop_seq[4] = {
FUSB_FIFO_TX_JAM_CRC,
FUSB_FIFO_TX_EOP,
FUSB_FIFO_TX_TXOFF,
FUSB_FIFO_TX_TXON};
FUSB_FIFO_TX_JAM_CRC,
FUSB_FIFO_TX_EOP,
FUSB_FIFO_TX_TXOFF,
FUSB_FIFO_TX_TXON };
/* Take the I2C2 mutex now so there can't be a race condition on sop_seq */
/* Get the length of the message: a two-octet header plus NUMOBJ four-octet
@@ -105,188 +100,155 @@ void fusb_send_message(const union pd_msg *msg)
sop_seq[4] = FUSB_FIFO_TX_PACKSYM | msg_len;
/* Write all three parts of the message to the TX FIFO */
fusb_write_buf(FUSB_FIFOS, 5, sop_seq);
fusb_write_buf(FUSB_FIFOS, msg_len, msg->bytes);
fusb_write_buf(FUSB_FIFOS, 4, eop_seq);
fusb_write_buf( FUSB_FIFOS, 5, sop_seq);
fusb_write_buf( FUSB_FIFOS, msg_len, msg->bytes);
fusb_write_buf( FUSB_FIFOS, 4, eop_seq);
FRToSI2C::unlock2();
}
uint8_t fusb_read_message(union pd_msg *msg)
{
if (!FRToSI2C::lock2())
{
asm("bkpt");
uint8_t fusb_read_message(union pd_msg *msg) {
if (!FRToSI2C::lock2()) {
return 1;
}
static uint8_t garbage[4];
uint8_t numobj;
// Read the header. If its not a SOP we dont actually want it at all
// But on some revisions of the fusb if you dont both pick them up and read them out of the fifo, it gets stuck
fusb_read_byte(FUSB_FIFOS);
fusb_read_byte( FUSB_FIFOS);
/* Read the message header into msg */
fusb_read_buf(FUSB_FIFOS, 2, msg->bytes);
fusb_read_buf( FUSB_FIFOS, 2, msg->bytes);
/* Get the number of data objects */
numobj = PD_NUMOBJ_GET(msg);
/* If there is at least one data object, read the data objects */
if (numobj > 0)
{
fusb_read_buf(FUSB_FIFOS, numobj * 4, msg->bytes + 2);
if (numobj > 0) {
fusb_read_buf( FUSB_FIFOS, numobj * 4, msg->bytes + 2);
}
/* Throw the CRC32 in the garbage, since the PHY already checked it. */
fusb_read_buf(FUSB_FIFOS, 4, garbage);
fusb_read_buf( FUSB_FIFOS, 4, garbage);
FRToSI2C::unlock2();
return 0;
}
void fusb_send_hardrst()
{
void fusb_send_hardrst() {
if (!FRToSI2C::lock2())
{
if (!FRToSI2C::lock2()) {
return;
}
/* Send a hard reset */
fusb_write_byte(FUSB_CONTROL3, 0x07 | FUSB_CONTROL3_SEND_HARD_RESET);
fusb_write_byte( FUSB_CONTROL3, 0x07 | FUSB_CONTROL3_SEND_HARD_RESET);
FRToSI2C::unlock2();
}
void fusb_setup()
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 12, 0);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
void fusb_setup() {
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
if (!FRToSI2C::lock2())
{
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
if (!FRToSI2C::lock2()) {
return;
}
}
/* Fully reset the FUSB302B */
fusb_write_byte(FUSB_RESET, FUSB_RESET_SW_RES);
fusb_write_byte( FUSB_RESET, FUSB_RESET_SW_RES);
osDelay(2);
if (!fusb_read_id())
{
if (!fusb_read_id()) {
return;
}
/* Turn on all power */
fusb_write_byte(FUSB_POWER, 0x0F);
fusb_write_byte( FUSB_POWER, 0x0F);
/* Set interrupt masks */
//Setting to 0 so interrupts are allowed
fusb_write_byte(FUSB_MASK1, 0x00);
fusb_write_byte(FUSB_MASKA, 0x00);
fusb_write_byte(FUSB_MASKB, 0x00);
fusb_write_byte(FUSB_CONTROL0, 0b11 << 2);
fusb_write_byte( FUSB_MASK1, 0x00);
fusb_write_byte( FUSB_MASKA, 0x00);
fusb_write_byte( FUSB_MASKB, 0x00);
fusb_write_byte( FUSB_CONTROL0, 0b11 << 2);
/* Enable automatic retransmission */
fusb_write_byte(FUSB_CONTROL3, 0x07);
fusb_write_byte( FUSB_CONTROL3, 0x07);
//set defaults
fusb_write_byte(FUSB_CONTROL2, 0x00);
fusb_write_byte( FUSB_CONTROL2, 0x00);
/* Flush the RX buffer */
fusb_write_byte(FUSB_CONTROL1,
FUSB_CONTROL1_RX_FLUSH);
fusb_write_byte( FUSB_CONTROL1,
FUSB_CONTROL1_RX_FLUSH);
/* Measure CC1 */
fusb_write_byte(FUSB_SWITCHES0, 0x07);
fusb_write_byte( FUSB_SWITCHES0, 0x07);
osDelay(10);
uint8_t cc1 = fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
uint8_t cc1 = fusb_read_byte( FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
/* Measure CC2 */
fusb_write_byte(FUSB_SWITCHES0, 0x0B);
fusb_write_byte( FUSB_SWITCHES0, 0x0B);
osDelay(10);
uint8_t cc2 = fusb_read_byte(FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
uint8_t cc2 = fusb_read_byte( FUSB_STATUS0) & FUSB_STATUS0_BC_LVL;
/* Select the correct CC line for BMC signaling; also enable AUTO_CRC */
if (cc1 > cc2)
{
fusb_write_byte(FUSB_SWITCHES1, 0x25);
fusb_write_byte(FUSB_SWITCHES0, 0x07);
if (cc1 > cc2) {
fusb_write_byte( FUSB_SWITCHES1, 0x25);
fusb_write_byte( FUSB_SWITCHES0, 0x07);
} else {
fusb_write_byte( FUSB_SWITCHES1, 0x26);
fusb_write_byte( FUSB_SWITCHES0, 0x0B);
}
else
{
fusb_write_byte(FUSB_SWITCHES1, 0x26);
fusb_write_byte(FUSB_SWITCHES0, 0x0B);
}
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
FRToSI2C::unlock2();
}
fusb_reset();
}
void fusb_get_status(union fusb_status *status)
{
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
if (!FRToSI2C::lock2())
{
void fusb_get_status(union fusb_status *status) {
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
if (!FRToSI2C::lock2()) {
return;
}
}
/* Read the interrupt and status flags into status */
fusb_read_buf(FUSB_STATUS0A, 7, status->bytes);
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
fusb_read_buf( FUSB_STATUS0A, 7, status->bytes);
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
FRToSI2C::unlock2();
}
}
enum fusb_typec_current fusb_get_typec_current()
{
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
if (!FRToSI2C::lock2())
{
enum fusb_typec_current fusb_get_typec_current() {
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
if (!FRToSI2C::lock2()) {
return fusb_tcc_none;
}
}
/* Read the BC_LVL into a variable */
enum fusb_typec_current bc_lvl = (enum fusb_typec_current)(fusb_read_byte(
FUSB_STATUS0) &
FUSB_STATUS0_BC_LVL);
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
enum fusb_typec_current bc_lvl = (enum fusb_typec_current) (fusb_read_byte(
FUSB_STATUS0) & FUSB_STATUS0_BC_LVL);
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
FRToSI2C::unlock2();
}
return bc_lvl;
}
void fusb_reset()
{
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
if (!FRToSI2C::lock2())
{
void fusb_reset() {
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
if (!FRToSI2C::lock2()) {
return;
}
}
/* Flush the TX buffer */
fusb_write_byte(FUSB_CONTROL0, 0x44);
fusb_write_byte( FUSB_CONTROL0, 0x44);
/* Flush the RX buffer */
fusb_write_byte(FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH);
fusb_write_byte( FUSB_CONTROL1, FUSB_CONTROL1_RX_FLUSH);
/* Reset the PD logic */
// fusb_write_byte( FUSB_RESET, FUSB_RESET_PD_RESET);
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
// fusb_write_byte( FUSB_RESET, FUSB_RESET_PD_RESET);
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
FRToSI2C::unlock2();
}
}
bool fusb_read_id()
{
bool fusb_read_id() {
//Return true if read of the revision ID is sane
uint8_t version = 0;
fusb_read_buf(FUSB_DEVICE_ID, 1, &version);
@@ -294,8 +256,7 @@ bool fusb_read_id()
return false;
return true;
}
uint8_t fusb302_detect()
{
uint8_t fusb302_detect() {
//Probe the I2C bus for its address
return FRToSI2C::probe(FUSB302B_ADDR);
}

View File

@@ -8,7 +8,12 @@
#include "stdlib.h"
#include "task.h"
#include "I2C_Wrapper.hpp"
#include "fusbpd.h"
void postRToSInit() {
// Any after RTos setup
// Any after RTos setup
FRToSI2C::FRToSInit();
#ifdef POW_PD
//Spawn all of the USB-C processors
fusb302_start_processing();
#endif
}

View File

@@ -14,7 +14,7 @@ void preRToSInit() {
eclic_priority_group_set(ECLIC_PRIGROUP_LEVEL4_PRIO0);
eclic_global_interrupt_enable();
hardware_init();
FRToSI2C::init();
FRToSI2C::FRToSInit();
gpio_bit_reset(OLED_RESET_GPIO_Port, OLED_RESET_Pin);
delay_ms(50);
gpio_bit_set(OLED_RESET_GPIO_Port, OLED_RESET_Pin);