[En-Nut-Discussion] SJA1000 driver

Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Wed Oct 21 19:19:59 CEST 2009


>>>>> "Petri" == Petri Hyötylä <phyotyla at gmail.com> writes:


    Petri> Hi I am using the original Ethernut3 with custom PCB connected to
    Petri> the expansion port.  All these are fine ideas but this is one of
    Petri> those things that have to be ready by yesterday (ASAP).  We
    Petri> happen to have AT90CAN128 boards in the lab so I'll go with one
    Petri> of those.  I'm guessing (hoping) that it will be fairly easy to
    Petri> get the CAN working and also the SPI slave code.

We use the AT90CAN128 successfull on several boards with Ethernut, on some
boards even without external RAM. Here the crucial CAN code

  // Init AT90CAN128 CAN controller
  canresult = NutRegisterDevice(&devAtCan, 0, 0);
  
  if (canresult) 
    fprintf_P(stdout, can_register_P, canresult);
  canInfoPtr = (CANINFO *) devAtCan.dev_dcb;

  // Set CAN bit rate
  CAN_SetSpeed(&devAtCan, CPS_SPEED);
  /*FIXME: It seems at least 4 MOBS need to be given */
  /* explicitly set up 3 receive Message Objects */
  /* Global Broadcast */
  AtCanEnableRx    (6,CPS_CMD, IS_EXTENDED, NOT_REMOTE, DEVICE_MASK,IS_EXTENDED, NOT_REMOTE);
  fprintf_P(stdout, PSTR("MOB for Global Broadcast id 0x%08lx mask 0x%08lx\n"), CPS_CMD, GLOBAL_BC_MASK);
  /* Crate Broadcast */

  AtCanEnableMsgObj(6,CPS_CMD|((uint32_t)base<<CRATE_SHIFT), IS_EXTENDED, NOT_REMOTE, DEVICE_MASK,IS_EXTENDED, NOT_REMOTE);
  fprintf_P(stdout, PSTR("MOB for Crate Broadcast  id 0x%08lx mask 0x%08lx\n"), 
            CPS_CMD|((uint32_t)base<<CRATE_SHIFT), DEVICE_MASK);
  /* Explicit Deviced */
  fprintf_P(stdout, PSTR("MOB for Device           id 0x%08lx mask 0x%08lx\n"), 
            CPS_CMD|((uint32_t)base<<CRATE_SHIFT)| (uint32_t)address << DEVICE_SHIFT, DEVICE_MASK);
  AtCanEnableMsgObj(7,CPS_CMD|((uint32_t)base<<CRATE_SHIFT)| (uint32_t)address << DEVICE_SHIFT, IS_EXTENDED, NOT_REMOTE, 
                    DEVICE_MASK,IS_EXTENDED, NOT_REMOTE);
            
  fprintf_P(stdout, PSTR("Starting CAN RX/TX loop...\n"));

  while(1)
    {
     if (CAN_TryRxFrame(&devAtCan, &canFrame) == 0)
        {
          crate = ID2CRATE(canFrame.id);
          device = ID2DEVICE(canFrame.id);
          command = ID2CMD(canFrame.id);
          if((crate == BROADCAST_ID) || ((crate == base) && (device == BROADCAST_ID)) || ((crate == base) && (device == address)))
            {
              activity = 0xff;
              switch(command)
                {
                case CMD_BOOTLD_CKSUM_REQ:
                  bootld_req(&canFrame, mute);
                  break;
                  
...
As our SPI devices can run quite fast and need byte access, the SPI access
is done in a separate thread like:
THREAD (ReadADS7835, arg)
{
  unsigned char pin;
  unsigned int value;
  unsigned int to_counter = 0;
  unsigned int last_set = 0x8000;
  /*
   * SCK and MOSI outputs need configuration, 
   * even if SPI mode is enabled.
   */
  cbi(PORTB, 1);
  sbi(DDRB, 1);
  cbi(PORTB, 2);
  sbi(DDRB, 2);
  cbi(PORTB, 0);
  sbi(DDRB, 0);
  /* set to 2 MHz  */
  SPCR = BV(MSTR) | BV(SPE) | BV(SPI2X) | BV(SPR0);
#define CPS84_OL_TIMEOUT 1000

  for (;;) 
...
      /*Read the ADC, Give a short low pulse to start and then keep CONV high*/
      SPDR = 0x7f;
      loop_until_bit_is_set(SPSR, SPIF);
      value  = (SPDR <<8);
      SPDR = 0xff;
      loop_until_bit_is_set(SPSR, SPIF);
      value  |=  (SPDR & 0xfc);
      value = value <<2;
      if (value & 0x8000)
        value &= 0x7fff;
      else
        value |= 0x8000;
      adc_values[DEVICE_ADC_V_ISENSE] = value;

...

Hope this helps
-- 
Uwe Bonnes                bon at elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------



More information about the En-Nut-Discussion mailing list