но недавно начал разбираться с ScmRTOS, и решил стараться оформлять все по максимому в С++. Начал оформление работы с SPI (AT91SAM7X256).
Написал в лоб. Создал базовый CustomSPI с нестатическим локом (локировать на время работы одного чипселекта). От него создал два класса для SPI0 и SPI1.
Каждому прописал по своему статическому обработчику прерываний с флагом.
Прошу сразу простить за корявый С++.
CODE
class TCustomSpi
{
public:
TCustomSpi() : Locker() { }
char SPI_BUFF[SPI_BUFF_LEN];
virtual void spi_transaction(uint8_t* sdata, uint32_t slen, uint8_t* rdata, uint32_t rlen) = 0;
protected:
bool spi_wait;
char cs_curent;
OS::TMutex Locker;
};
class TSpi0 : public TCustomSpi
{
public:
TSpi0 () {init_spi();}
void configure_chipselect(uint32_t ConfigCS, uint32_t chipselect);
void change_chipselect(uint32_t chipselect);
void spi_transaction(uint8_t* sdata, uint32_t slen, uint8_t* rdata, uint32_t rlen);
protected:
void init_spi();
static OS_INTERRUPT void spi_RXBUFF();
static OS::TEventFlag Ready;
};
...
extern TSpi0 spi0;
extern TSpi1 spi1;
// Обработчик из cpp
OS_INTERRUPT void TSpi0::spi_RXBUFF(void)
{
OS::TISRW ISR;
// Clear interrupt
volatile dword Tmp = *AT91C_SPI0_SR;
if ((Tmp&AT91C_SPI_RXBUFF)!=0) spi0.Ready.SignalISR();
}
Все работает. Но смотрю на это и понимаю, что коряво. Все должно быть гибче. Может кто может поделиться мыслями и пимерами, как это должно быть?
Постоянно в конечной плате еще на этапе промежуточных прототипов плавают адреса, чипселекты и тд. Хочется оформить так, чтобы поменяв только в одном месте define
для каждого потребителя SPI его номер(0,1) и чипселект(0..3) можно было добиться его корректной работы. При этом не наплодить много лишнего кода съедающего память
и время работы.
Возможно правильно будеть свалить оба spi в один класс со статическими методами, а от него породить по экземпляру на каждый чипселект, где на стадии создания
будет определяться номер spi и его чипселект. Но тоже как-то мутно.
Поделитесь своими идеями, как это лучше сделать.