mirror of
https://github.com/Ralim/IronOS.git
synced 2025-02-26 07:53:55 +00:00
Further work on Pinecil compile
This commit is contained in:
@@ -12,7 +12,8 @@ SemaphoreHandle_t FRToSI2C::I2CSemaphore;
|
||||
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
|
||||
#define FLAG_TIMEOUT 1000
|
||||
|
||||
void FRToSI2C::CpltCallback() {
|
||||
void FRToSI2C::CpltCallback()
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
@@ -20,28 +21,31 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,30 +53,34 @@ 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;
|
||||
}
|
||||
}
|
||||
@@ -86,26 +94,32 @@ 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
|
||||
@@ -114,15 +128,17 @@ 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;
|
||||
}
|
||||
}
|
||||
@@ -131,7 +147,8 @@ 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;
|
||||
|
||||
@@ -140,13 +157,18 @@ 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();
|
||||
}
|
||||
}
|
||||
@@ -155,10 +177,11 @@ 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;
|
||||
@@ -170,9 +193,11 @@ 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;
|
||||
@@ -180,7 +205,8 @@ 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;
|
||||
@@ -190,21 +216,23 @@ 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;
|
||||
@@ -216,9 +244,11 @@ 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;
|
||||
@@ -228,13 +258,15 @@ 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 == (Size - 1));
|
||||
for (count = 0; count < Size; count++)
|
||||
{
|
||||
pData[count] = i2c_byte_read(count == (uint32_t)(Size - 1));
|
||||
}
|
||||
|
||||
/* if not sequential write, then send stop */
|
||||
@@ -243,17 +275,20 @@ 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) {
|
||||
void FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data)
|
||||
{
|
||||
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) {
|
||||
uint8_t *pData, uint16_t Size)
|
||||
{
|
||||
if (!lock())
|
||||
return;
|
||||
|
||||
@@ -261,15 +296,19 @@ void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
|
||||
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) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (timeout % 5 == 0)
|
||||
{
|
||||
i2c_stop();
|
||||
}
|
||||
}
|
||||
@@ -278,10 +317,11 @@ 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;
|
||||
@@ -293,9 +333,11 @@ 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;
|
||||
@@ -305,9 +347,11 @@ void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
|
||||
/* 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;
|
||||
@@ -320,7 +364,8 @@ void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
|
||||
unlock();
|
||||
}
|
||||
|
||||
void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||
void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size)
|
||||
{
|
||||
if (!lock())
|
||||
return;
|
||||
uint32_t count = 0;
|
||||
@@ -328,13 +373,18 @@ void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||
|
||||
/* 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) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (timeout % 5 == 0)
|
||||
{
|
||||
i2c_stop();
|
||||
}
|
||||
}
|
||||
@@ -343,10 +393,11 @@ 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;
|
||||
@@ -358,9 +409,11 @@ 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;
|
||||
@@ -370,9 +423,11 @@ void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||
/* 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;
|
||||
@@ -385,7 +440,8 @@ void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||
unlock();
|
||||
}
|
||||
|
||||
bool FRToSI2C::probe(uint16_t DevAddress) {
|
||||
bool FRToSI2C::probe(uint16_t DevAddress)
|
||||
{
|
||||
if (!lock())
|
||||
return false;
|
||||
i2c_start();
|
||||
@@ -393,14 +449,16 @@ 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;
|
||||
@@ -422,17 +480,20 @@ 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);
|
||||
|
||||
27
workspace/TS100/Core/BSP/Pine64/Model_Config.h
Normal file
27
workspace/TS100/Core/BSP/Pine64/Model_Config.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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_ */
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "FreeRTOSConfig.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "portmacro.h"
|
||||
@@ -6,36 +7,32 @@
|
||||
#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
|
||||
@@ -47,52 +44,51 @@ 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:
|
||||
//on User and Machine ECALL, handler the request
|
||||
case 8:
|
||||
case 11:
|
||||
{
|
||||
if (arg1 == IRQ_DISABLE)
|
||||
{
|
||||
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;
|
||||
//zero out mstatus.mpie
|
||||
clear_csr(mstatus, MSTATUS_MPIE);
|
||||
}
|
||||
default:
|
||||
else if (arg1 == IRQ_ENABLE)
|
||||
{
|
||||
/* 异常处理 */
|
||||
extern uintptr_t handle_trap(uintptr_t mcause, uintptr_t sp);
|
||||
handle_trap(mcause,sp);
|
||||
//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;
|
||||
}
|
||||
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 目的是在软中断内进行任务上下文切换
|
||||
@@ -100,24 +96,22 @@ 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中被调用
|
||||
*
|
||||
@@ -125,23 +119,22 @@ 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();
|
||||
@@ -149,45 +142,42 @@ 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
|
||||
*
|
||||
@@ -195,11 +185,10 @@ 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
|
||||
*
|
||||
@@ -207,15 +196,14 @@ 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 初始化任务栈帧
|
||||
*
|
||||
@@ -224,30 +212,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--;
|
||||
|
||||
@@ -255,25 +243,24 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
@@ -281,39 +268,38 @@ 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
|
||||
*
|
||||
@@ -321,21 +307,20 @@ 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 初始化软中断
|
||||
*
|
||||
@@ -343,11 +328,10 @@ 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 调度启动前的初始化准备
|
||||
*
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
#ifndef PINE_PORTMACRO_H
|
||||
#define PINE_PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
#include "riscv_encoding.h"
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
@@ -20,123 +19,128 @@ 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
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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 );
|
||||
#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);
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
/*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;
|
||||
|
||||
#if CONFIG_SYSTEMVIEW_EN
|
||||
#define portEND_SWITCHING_ISR(xSwitchRequired) { if( xSwitchRequired != pdFALSE) { traceISR_EXIT_TO_SCHEDULER(); portYIELD(); } else {traceISR_EXIT(); } }
|
||||
#ifdef 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 */
|
||||
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user