реклама на сайте
подробности

 
 
> C++ и работа с однотипной аппаратурой, Варианты оформления работы с однотипным железом на примере SPI
BAT
сообщение Dec 17 2009, 13:48
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 35
Регистрация: 22-12-05
Пользователь №: 12 556



Хочется написать прототип работы с железом так, чтоб потом по нему оформлять все остальные работы. В МК раньше работал только на чистом С,
но недавно начал разбираться с 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 и его чипселект. Но тоже как-то мутно.
Поделитесь своими идеями, как это лучше сделать.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
AHTOXA
сообщение Dec 27 2009, 08:09
Сообщение #2


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(BAT @ Dec 17 2009, 18:48) *
Все работает. Но смотрю на это и понимаю, что коряво. Все должно быть гибче. Может кто может поделиться мыслями и пимерами, как это должно быть?

Вот как у меня сделано: Прикрепленный файл  spi_template.rar ( 2.54 килобайт ) Кол-во скачиваний: 122


В конечном проекте пишу

hw.h:
Код
// SPI1:
  typedef spi_t<SPI_1> spi1_t;
  extern spi1_t spi1;
  
  // чипселект для ЦАП-а
  typedef Pin<'C', 9, 'L'> PIN_DAC_CS;
  
  // ЦАП:
  typedef ad5663_t<PIN_DAC_CS> dac_t;
  extern dac_t dac;


hw.cpp:
Код
spi1_t spi1;
  dac_t dac(spi1);
  eeprom_t at25(spi1);


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 14:47
Рейтинг@Mail.ru


Страница сгенерированна за 0.01354 секунд с 7
ELECTRONIX ©2004-2016