collapse

* Posts Recentes

Amplificador - Rockboard HA 1 In-Ear por almamater
[Ontem às 19:13]


O que é isto ? por KammutierSpule
[26 de Março de 2024, 19:35]


Bateria - Portátil por almamater
[25 de Março de 2024, 22:14]


Emulador NES em ESP32 por dropes
[13 de Março de 2024, 21:19]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]


Meu novo robô por josecarlos
[06 de Janeiro de 2024, 16:46]


Laser Engraver - Alguém tem? por almamater
[16 de Dezembro de 2023, 14:23]

Autor Tópico: The Maple - ARM 100% compatível com codigo Arduino  (Lida 5976 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

StarRider

  • Visitante
The Maple - ARM 100% compatível com codigo Arduino
« em: 08 de Dezembro de 2010, 13:29 »
Boas,

Não sei se já conhecem, de qualquer forma vale uma vista de olhos para quem usa a "linguagem" Arduino e quer
evoluir para um ARM e continuar a usar programação 100% compatível "á la" Arduino

http://leaflabs.com/devices/maple/

Abraços
PA
« Última modificação: 08 de Dezembro de 2010, 16:28 por StarRider »

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: The Maple - ARM 100% compatível com codigo Arduino
« Responder #1 em: 08 de Dezembro de 2010, 14:11 »
Dois tópicos abaixo deste...
Maple - ARM Cortex-M3 (Programmable with Arduino Language)

Isso teoricamente é bonito, mas na prática estão a fazer pior ainda que as bibliotecas do arduino e a esconder a porcaria com um clock mais elevado...
Nem o i2c é nativo é bit-banged se achas isso bom...
Avr fanboy

Offline GnGz

  • Mini Robot
  • *
  • Mensagens: 665
Re: The Maple - ARM 100% compatível com codigo Arduino
« Responder #2 em: 08 de Dezembro de 2010, 14:26 »
Para evoluir eu diria o mbed ou mesmo aprender o nativo

StarRider

  • Visitante
Re: The Maple - ARM 100% compatível com codigo Arduino
« Responder #3 em: 08 de Dezembro de 2010, 16:45 »
Dois tópicos abaixo deste...
Maple - ARM Cortex-M3 (Programmable with Arduino Language)

Isso teoricamente é bonito, mas na prática estão a fazer pior ainda que as bibliotecas do arduino e a esconder a porcaria com um clock mais elevado...
Nem o i2c é nativo é bit-banged se achas isso bom...

Boas,

Não disse que era bom nem que era mau, apesar de ter "hands on" com o dito cujo...  mas sei que o que para uns é mau para outros é bom, e
temos que respeitar isso mesmo, pois só assim podemos também ser respeitados.

De resto, e em especial para todos os que comentam apenas numa sabe teórica, volto a dizer, nada como experimentar para depois comentar...

Abraços
PA

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: The Maple - ARM 100% compatível com codigo Arduino
« Responder #4 em: 08 de Dezembro de 2010, 16:49 »
O criador deles posta muito no forum dos Arduinos, das primeiras coisas que ele disse é que as bibliotecas CMSIS não valem nada, passados 6 meses apresenta i2c bitbanged quando todos os arm's têm pelo menos um i2c nativo, mas tem mais falhas, obviamente tal como o arduino podes programar algo sem perceber nada do que está por baixo, e ai tem sempre os seus pontos positivos, mas tem sempre falhas.
Avr fanboy

StarRider

  • Visitante
Re: The Maple - ARM 100% compatível com codigo Arduino
« Responder #5 em: 08 de Dezembro de 2010, 16:58 »
Para evoluir eu diria o mbed ou mesmo aprender o nativo

Boas,

Para mim, e penso que sobre isso nem sequer existe lugar a duvida, passar de um AVR para um ARM é evolução, mesmo que se continue preso
a uma qualquer linguagem. Agora, se por "evoluir" entendes como base o "espartilho" do Arduino, pois ai para evoluir nem sequer é necessário
trocar de uC, basta usar um verdadeiro compilador de C/C++ com o AVR instalado nas placas Arduino.

Por outro lado, quem usa a "linguagem" Arduino e quer ter mais PODER DE PROCESSAMENTO e todas as vantagens dos periféricos do STM32F
sem ter que passar por uma curva de aprendizagem longa e penosa, pois é óbvio que por qualquer que seja o ângulo de analise será sempre
uma evolução.

Pode não ser o "passo seguinte" ideal, esse seria de facto evoluir para uma base nativa de C/C++ e usar toda a potencialidade do uC, mas
pelo menos é um "empurram" na direcção certa.

Cumprimentos,
PA

« Última modificação: 08 de Dezembro de 2010, 17:32 por StarRider »

StarRider

  • Visitante
Re: The Maple - ARM 100% compatível com codigo Arduino
« Responder #6 em: 08 de Dezembro de 2010, 17:45 »
O criador deles posta muito no forum dos Arduinos, das primeiras coisas que ele disse é que as bibliotecas CMSIS não valem nada, passados 6 meses apresenta i2c bitbanged quando todos os arm's têm pelo menos um i2c nativo, mas tem mais falhas, obviamente tal como o arduino podes programar algo sem perceber nada do que está por baixo, e ai tem sempre os seus pontos positivos, mas tem sempre falhas.

Boas,

Vais me desculpar mas penso que estas equivocado nesse aspecto, se consultares o esquema do Maple e a implementação do I2C vais ver
que este tem 2 portas I2C mapeadas aos pinos PB6 (SCL) e PB7 (SDA) para o I2C1 e aos pinos PB10 (SCL) e PB11 (SDA) para o I2C1 que
correspondem exactamente ao periféricos I2C do STM32 F103RB.

Por outro lado, a implementação dos drivers ainda não esta completa nem disponível, pelo que não sei de onde vem essa informação que
o Maple usa bitbanged, tanto mais que toda a informação no site aponta no sentido totalmente oposto:

http://static.leaflabs.com/pub/leaflabs/maple-hardware/rev3/maple-rev3-schematics.pdf
http://leaflabs.com/docs/maple/i2c

Penso que o projecto Maple tem uma mais valia e que o seu autor merece o nosso aplauso, seja qual for a nossa posição perante a filosofia
"Arduino" e seus clones.

Abraços,
PA
« Última modificação: 08 de Dezembro de 2010, 17:48 por StarRider »

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: The Maple - ARM 100% compatível com codigo Arduino
« Responder #7 em: 08 de Dezembro de 2010, 18:25 »
Citar
Today is a great day! I2C (software bit banged I2C - not hardware DMA) is working on the Maple.
The alpha software released, for testing only, from Leaflabs is working on my Maxim-IC RTC (DS3231/DS1307).
Other devices are in the process of being tested?

They needed an Arduino hacker to show them how to make it work- right!!!!
Daqui:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1274652722/180

E penso que ainda não passou de bitbanged para a frente, mas isso se tens o IDE instalado podes procurar no respectivo .h e .c/.cpp como é.
Avr fanboy

StarRider

  • Visitante
Re: The Maple - ARM 100% compatível com codigo Arduino
« Responder #8 em: 08 de Dezembro de 2010, 21:33 »
Citar
Today is a great day! I2C (software bit banged I2C - not hardware DMA) is working on the Maple.
The alpha software released, for testing only, from Leaflabs is working on my Maxim-IC RTC (DS3231/DS1307).
Other devices are in the process of being tested?

They needed an Arduino hacker to show them how to make it work- right!!!!
Daqui:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1274652722/180

E penso que ainda não passou de bitbanged para a frente, mas isso se tens o IDE instalado podes procurar no respectivo .h e .c/.cpp como é.

Boas,

Penso que na fase actual do projecto Maple a ideia é mesmo usar I2C por hardware, pois realmente usar bitbanged é uma estupidez e um
desperdício de recursos.

Por outro lado, estava aqui a olhar para as boards STM32-Discovery e estava a pensar até que ponto seria possível criar umas libs, defines e
alterar o startup de modo a compilar "código" Arduino no Keil (ou noutra toolchain) ... é perfeitamente viável, haja tempo e pachorra...  vamos
ver no que dá.

Abraços,
PA



Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: The Maple - ARM 100% compatível com codigo Arduino
« Responder #9 em: 08 de Dezembro de 2010, 21:36 »
E porque é que não fazes como o tipico programador de micro-controladores, fazes uma série de funções para inicializar o que queres usar, e depois mais umas quantas funções para as usar, olha este exemplo super simples para inicializar e mandar caracteres ou strings via serial num atmega328, mais limpo é complicado, só se fizesse em assembly, é limpinho e simples de usar, comparado por exemplo com a biblioteca serial do arduino é mil vezes mais limpo e leve, está bem que não faz metade coisas que faz a serial do arduino, mas se precisas de mais uso o sprintf ou faço um sprintf levezinho.
Código: [Seleccione]
#include "USART.h"
#include <avr/io.h>

#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

void USART_init(void){

UBRR0H = (uint8_t)(BAUD_PRESCALLER>>8);
UBRR0L = (uint8_t)(BAUD_PRESCALLER);
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
UCSR0C = (3<<UCSZ00);
}


unsigned char USART_receive(void){

while(!(UCSR0A & (1<<RXC0)));
return UDR0;

}


void USART_putchar( unsigned char data){

while(!(UCSR0A & (1<<UDRE0)));
UDR0 = data;

}


void USART_putstring(char* StringPtr)
{
   while (*StringPtr != 0x00) {
      USART_putchar(*StringPtr);
      StringPtr++;
   }
}
« Última modificação: 08 de Dezembro de 2010, 21:38 por senso »
Avr fanboy

StarRider

  • Visitante
Re: The Maple - ARM 100% compatível com codigo Arduino
« Responder #10 em: 08 de Dezembro de 2010, 23:28 »
E porque é que não fazes como o tipico programador de micro-controladores, fazes uma série de funções para inicializar o que queres usar, e depois mais umas quantas funções para as usar, olha este exemplo super simples para inicializar e mandar caracteres ou strings via serial num atmega328, mais limpo é complicado, só se fizesse em assembly, é limpinho e simples de usar, comparado por exemplo com a biblioteca serial do arduino é mil vezes mais limpo e leve, está bem que não faz metade coisas que faz a serial do arduino, mas se precisas de mais uso o sprintf ou faço um sprintf levezinho.

Boas,

A ideia de "compilar código Arduino" no Keil era puramente académica e o seu único propósito era demonstrar que se pode fazer coisas numa
toolchain ARM de forma fácil e rápida... 

Esse forma de usar a UART é realmente simples, mas por vezes pode ser simples de mais, não tens tratamento de erros, não contemplas timeouts
e mais outras questões que por vezes em determinados projectos têm mesmo que ser contemplados.

Usamos a UART (e I2C) por intermédio de interrupts e com uma circular buffer para enviar e receber dados em background independente do flow
do firmware. É uma solução mas pesada mas com muitas vantagens, mas como disse tudo dependo da finalidade do código que estás a
desenvolver e se vai ser utilizado num sistema critico ou num simples projecto caseiro.

Aqui fica um exemplo do que usamos por estes lados:

Código: [Seleccione]
#include "LPC22xx.h"
#include "orbiter_548P.h"
#include <string.h>
#include <stdio.h>
#include <setjmp.h>


//----- USARTS buffers                     
typedef struct {
uint8 r_buffer[RXBUFSIZE];
int16 rw_index,rr_index,r_count;
  int8  r_buffer_overflow;

uint8 t_buffer[TXBUFSIZE];
int16 tw_index,tr_index,t_count;
} TUART;

TUART uart0;
TUART uart1;

extern volatile int16  SystemReady;
extern TSetup TheOrbiter;
extern uint8  Keybuffer;

jmp_buf i2cerror;


//=============================================================================
// UARTS
//=============================================================================
//-----------------------------------------------------------------------------
// UART0 Interrupt handler
void uart0int (void) __irq
{
unsigned char chr,iir; 

   iir=U0IIR; // reading U0IIR will clear the interrupt flags
   switch(iir & 0x0F) {   
  case 0x06:  // Receive line status/error
chr=U0LSR; // read U0LSR to clear the interrupt flag
break;
case 0x04:  // Receive data available
chr=U0RBR;
    if (chr==6) { // ACK get system ready
      if (SystemReady)
      PutCharUART0(TheOrbiter.Burst ? 'A' : 'P');
        else
      PutCharUART0('0');
    } else {
    uart0.r_buffer[uart0.rw_index]=chr;     
    if (++uart0.rw_index == RXBUFSIZE)
    uart0.rw_index=0;
    if (++uart0.r_count == RXBUFSIZE) {
      uart0.r_count=0;
      uart0.r_buffer_overflow=1;
    }
    }
      break;
case 0x0C:  // Character time out
chr=U0RBR; // read U0RBR to clear the interrupt flag
break;
    case 0x02:  // THRE interrupt tx buffer empty 
    U0THR = uart0.t_buffer[uart0.tr_index];
  if (++uart0.tr_index == TXBUFSIZE)
  uart0.tr_index=0;
uart0.t_count--;
    if (uart0.t_count==0)
      U0IER = UIERRBR; //Disable tx buf empty interrupt
      break;
default:
      break;
}
VICVectAddr = 0;        // Acknowledge Interrupt
}
//-----------------------------------------------------------------------------
//
#pragma diag_suppress 550
void InitUARTS(void)
{
uint8 dummy;

  //===== UART0
memset(&uart0,0,sizeof(TUART)); //Clear uarto control structure
  PINSEL0_bit->P0_0=0x1; // Set pin function to TxD (UART0)
  PINSEL0_bit->P0_1=0x1; // Set pin function to RxD (UART0)
  //Disable UART INTs
  U0IER = 0;     
  //Set baudrate
  U0LCR_bit->DLAB = 1;
  U0DLL = USBBAUDRATE;  //U0DLL = USBBAUDRATE & 0x00ff;
  U0DLM = 0;   //U0DLM = USBBAUDRATE  >> 8) & 0x00ff;
U0LCR_bit->DLAB = 0;
  //Set mode
  U0LCR = 0x3;    //8 bit word length 1 stop bit No parity
  //Disable the FIFO
  U0FCR = 0x00;
  //Set VIC
  VICVectAddr3 = (unsigned int)&uart0int;
  VICVectCntl3 = 0x20 | INT_UART0; // Enable vector interrupt for UART0.
  VICIntEnable = INT_UART0_bit;    // Enable UART0 interrupt.
  // Ensure that no interrupts sources are active
  dummy = U0LSR;
  //Enable UART0 interrupts
  U0IER = UIERRBR; //Enable byte received interrupt, Tx buf empty interrupt only active if date to send is present.


#pragma diag_default 550
//-----------------------------------------------------------------------------
//
void PutCharUART0(unsigned char byte)
{     
while(uart0.t_count==TXBUFSIZE)
  ; // do nothing

#ifdef NOINTGUIDING
ProcessGuiding(); // EGNOS project
#endif

if (uart0.t_count || ((U0LSR & ULSRTHRE)==0)) {
  DisableInts();
    uart0.t_buffer[uart0.tw_index]=byte;
    uart0.t_count++;
    if (++uart0.tw_index==TXBUFSIZE)
    uart0.tw_index=0;
    U0IER = UIERRBR | UIERTHRE;  //Enable byte received and Tx buf empty interrupt
    RestoreInts();
  } else 
   U0THR = byte;
}
//---------------------------------------------------------------------------
//
void PutStringUART0(char *data)
{
   while(*data )       
      PutCharUART0(*data++);
}
//-----------------------------------------------------------------------------
//                           
uint8 GetCharUART0(int8 wait)
{                                     
uint8 data=0;                             

if (uart0.r_count==0) {
  if (wait) {
    while(uart0.r_count==0)
      ;  //  Do nothing! - TODO: control Timeout
    } else
    return 0;

   
#ifdef NOINTGUIDING
ProcessGuiding(); // EGNOS project
#endif

  DisableInts();
data=uart0.r_buffer[uart0.rr_index];
if (++uart0.rr_index == RXBUFSIZE)
uart0.rr_index=0;
uart0.r_count--;
  RestoreInts();

return data;
}
//------------------------------------------------------------------------------
// Peek a char
uint8 PeekUART0(void)
{
if (uart0.r_count)
return uart0.r_buffer[uart0.rr_index];
else
return 0;
}
//------------------------------------------------------------------------------
// Clean Uart
void ClearUART0(void)
{
  while (GetCharUART0(0));
}
//------------------------------------------------------------------------------
//
int16 GetStringUART0(char *buffer, int16 length)
{                                                       
int16 count=0,timeleft=32000;
  uint8 chr;
if (uart0.r_count) {
length--;
do {
chr=GetCharUART0(0);
  if (chr && chr!=SUFIXCHAR) {
buffer[count++]=chr;     
timeleft=32000; // reset timer
} else {
timeleft--;
}
} while ((chr!=SUFIXCHAR) && (chr!='#') && (count<length) && timeleft);
if (!timeleft)
count=0;     
buffer[count]=0;
}
return count;
}


     
//=============================================================================
// I2C
//=============================================================================
#define STA  0x20
#define SIC  0x08
#define SI   0x08
#define STO  0x10
#define STAC 0x20
#define AA   0x04

//-----------------------------------------------------------------------------
//
void InitI2C(void)
{
I2CONCLR = 0xFF;
PINSEL0  |= 0x50;   //  Set pinouts as scl and sda
  I2SCLL   =19;       //speed at 100Khz for a VPB Clock Divider  = 4 at 14 MHz
  I2SCLH   =19;
// I2SCLL=60;       //speed at 375Khz for a VPB Clock Divider  = 1
// I2SCLH=70;       // Pierre Seguin's origional values.
I2CONSET = 0x40;    //Active Master Mode on I2C bus
}
//-----------------------------------------------------------------------------
//
void StopI2C(void)
{
I2CONCLR = SIC;
  I2CONSET = STO;
while((I2CONSET&STO)) ;   // wait for Stopped bus I2C
}
//-----------------------------------------------------------------------------
//
void SetAddressI2C(unsigned char Addr_S)
{
unsigned char r;
  I2CONCLR = 0xFF;             // clear I2C - included if User forgot to "StopI2C()"
                               // else this function would hang.
  I2CONSET = 0x40;             // Active Master Mode on I2C bus
  if((Addr_S & 0x01))          // test if it's reading
  I2CONSET = STA | AA;       // set STA - allow master to acknowlege slave;
  else
  I2CONSET = STA;            // set STA dont allow acknowledges;

  while(I2STAT!=0x08) ;        // Wait for start to be completed

I2DAT    = Addr_S;           // Charge slave Address
  I2CONCLR = SIC | STAC;       // Clear i2c interrupt bit to send the data
 
  while( ! ( I2CONSET & SI)) ; // wait till status available
 
  r=I2STAT;                    // read Status. See standard error codes pdf (link in manual).
  if(!(Addr_S & 0x01)) {       // if we are doing a write
  if (r != 0x18) {           // look for "SLA+W has been transmitted; ACK has been received"
    if ( r==0x20 )           // check for "SLA+W has been transmitted; NOT ACK has been received"
      longjmp(i2cerror,1);   // no acknowlege - probably no device there. Return a 1 in longjmp
      longjmp(i2cerror,r);     // other error - return status code in longjmp
    }
} else {
  if (r != 0x40) {           // look for "SLA+R has been transmitted; ACK has been received"
    if ( r==0x48 )           // check for "SLA+R has been transmitted; NOT ACK has been received"
      longjmp(i2cerror,1);   // no acknowlege - probably no device there. Return a 1 in longjmp
      longjmp(i2cerror,r);     // other error - return status code in longjmp
    }
  }
}
//-----------------------------------------------------------------------------
//
uint8 ReadI2C(void)
{
  uint8 r;
  I2CONCLR = SIC;                  // clear SIC;
 
  while( ! (I2CONSET & 0x8));      // wait till status available
 
  r=I2STAT;                        // check for error
  if (r != 0x50)                   // look for "Data byte has been received; ACK has been returned"
  longjmp(i2cerror,r);           // read fail
   
   return I2DAT;
}
//-----------------------------------------------------------------------------
//
void WriteI2C(uint8 data)
{
uint8 r;

I2DAT    = data;                // Charge Data
  I2CONCLR = 0x8;                 // SIC; Clear i2c interrupt bit to send the data
 
  while( ! (I2CONSET & 0x8));     // wait till status available
  r=I2STAT;
 
  if (r != 0x28)                  // look for "Data byte in S1DAT has been transmitted; ACK has been received"
  longjmp(i2cerror,r);          // write fail
}
//-----------------------------------------------------------------------------
         
/*====================================================================================*/
// EOF  uart_i2c_drv.cpp