char tx_buffer[20];
char rx_buffer[20];
spi_open();
while(spi_read(rx_buffer,20))
{
app_processa_resposta(rx_buffer,tx_buffer);
spi_write(tx_buffer,20);
}
/* state machines, definicoes, etc */
enum {
SPI_SM_READ_START=0,
SPI_SM_READ_BIT0,
...
SPI_SM_READ_END
};
/* funcoes intrinsicas do driver para arm9-power-vrx++ */
unsigned char spi_read_remendex()
{
unsigned char data = 0;
for(state = 0; state != SPI_SM_READ_END; state++)
{
switch(state)
{
...
case SPI_SM_READ_BIT4:
data = (data<<1) + gpio_read(SPI_PIN_MISO);
break;
...
}
}
return data;
}
/* funcoes visiveis pela api padrao */
int spi_read(char *rx_buffer,int size)
{
int i;
for(i=0;i!=size;i++)
rx_buffer[i] = spi_read_remendex();
return size;
}
/* funcoes intrinsicas do driver para hc908 */
unsigned char spi_read_byte()
{
while(!HC908_SPI_RXREADY);
return HC908_SPI_RX;
}
/* funcoes visiveis pela api padrao */
int spi_read(char *rx_buffer,int size)
{
int i;
for(i=0;i!=size;i++)
rx_buffer[i] = spi_read_byte();
return size;
}
/* estados usados em todas as tasks */
enum
{
STATE_DEFAULT,
STATE_IDLE,
STATE_READ,
STATE_WRITE,
STATE_BUSY
};
/* task para spi */
void spi_task(Message *msg)
{
static state = STATE_DEFAULT;
if(state == STATE_DEFAULT)
{
spi_init_interface(msg->init_parameters);
state = STATE_IDLE;
}
if(state == STATE_IDLE)
{
msg->state = STATE_BUSY;
if(msg->state == STATE_READ)
{
msg->size = spi_read(msg->data,msg->size);
}
if(msg->state == STATE_WRITE)
{
msg->size = spi_write(msg->data,msg->size);
}
msg->to = msg->from;
msg->from = SPI_TASK;
send(msg);
state = STATE_IDLE;
}
}
/* em algum lugar, uma lista das tasks, claro */
enum
{
APP_TASK,
SPI_TASK,
TIME0_ISR.,
...
};
/* task cliente */
void app_task(Message *msg)
{
char rx_buffer[20];
static state = STATE_IDLE;
if(state == IDLE)
{
state = STATE_BUSY;
msg->data = rx_buffer;
msg->size = 20;
msg->from = APP_TASK;
msg->to = SPI_TASK;
msg->state = STATE_READ;
send(msg);
}
if(state == STATE_READ)
{
printf("recebido da spi %d bytes: %s\n",msg->size,msg->data);
free_message(msg);
state = STATE_IDLE;
}
}
interrupt timer0
{
Messagem *msg;
msg = new_message();
msg->from = TIMER0_ISR;
msg->to = APP_TASK;
send(msg);
}
void spi_task(Message *msg)
{
static int state = STATE_DEFAULT;
static int count = 0;
if(state == STATE_DEFAULT)
{
spi_init_interface(msg->init_parameters);
state = STATE_IDLE;
}
if(state == STATE_IDLE)
{
msg->state = msg->state;
count = 0;
}
if(state == STATE_READ)
{
if(count!=msg->size)
msg->data[count++] = spi_read_byte();
}
if(msg->state == STATE_WRITE)
{
if(count!=msg->size)
spi_write_byte(msg->data[count++]);
else
state = STATE_DONE;
}
if(state == STATE_DONE)
{
msg->to = msg->from;
msg->from = SPI_TASK;
send(msg);
state = STATE_IDLE;
}
}
enum {
STATE_IDLE,
STATE_STOP,
STATE_DATA0,
STATE_DATA1,
STATE_DATA2,
STATE_DATA3,
STATE_DATA4,
STATE_DATA5,
STATE_DATA6,
STATE_DATA7,
STATE_START
};
volatile unsigned char TX_STATE = STATE_IDLE;
volatile unsigned char TX_DATA;
volatile unsigned char RX_STATE = STATE_IDLE;
volatile unsigned char RX_DATA;
void timer(void) interrupt 6 {
TOF = 0;
switch(RX_STATE) {
case STATE_START:
if(PTA0) return;
RX_DATA=0;
break;
case STATE_DATA0:
case STATE_DATA1:
case STATE_DATA2:
case STATE_DATA3:
case STATE_DATA4:
case STATE_DATA5:
case STATE_DATA6:
case STATE_DATA7:
RX_DATA>>=1;
if(PTA0) RX_DATA|=0x80;
break;
case STATE_STOP:
break;
case STATE_IDLE:
switch(TX_STATE) {
case STATE_START:
DDRA0 = 1;
PTA0 = 0;
break;
case STATE_DATA0:
case STATE_DATA1:
case STATE_DATA2:
case STATE_DATA3:
case STATE_DATA4:
case STATE_DATA5:
case STATE_DATA6:
case STATE_DATA7:
PTA0=TX_DATA&1;
TX_DATA>>=1;
break;
case STATE_STOP:
PTA0 = 1;
DDRA0=0;
break;
case STATE_IDLE:
return;
}
TX_STATE--;
return;
}
RX_STATE--;
return;
}
void putchar(char c) {
while(TX_STATE|RX_STATE);
TX_DATA=c;
TX_STATE=STATE_START;
if(c=='\n') putchar('\r');
}
char getchar() {
while(RX_STATE|TX_STATE);
RX_STATE=STATE_START;
while(RX_STATE);
return RX_DATA;
}
ivan escreveu:...eu a princípio implementaria uma estrutura de SW aonde o cliente solicitaria serviços aos drivers...
...blocantes ou não, seria uma particularidade da interface com a camada física...
Voltar para Visual C++/C/C++/C#
Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante