Example #1
0
/////////////////////////////////////////////////////////////////////////////
// This hook is called after startup to initialize the application
/////////////////////////////////////////////////////////////////////////////
void APP_Init(void)
{
  // initialize all LEDs
  MIOS32_BOARD_LED_Init(0xffffffff);


  // initialize SPI interface
  // ensure that fast pin drivers are activated
  MIOS32_SPI_IO_Init(SLAVE_SPI, MIOS32_SPI_PIN_SLAVE_DRIVER_STRONG);

  // init SPI port
  MIOS32_SPI_TransferModeInit(SLAVE_SPI, MIOS32_SPI_MODE_SLAVE_CLK1_PHASE1, MIOS32_SPI_PRESCALER_128);

  // start task
  xTaskCreate(TASK_SPI_Handler, (signed portCHAR *)"SPI_Handler", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_SPI_HANDLER, NULL);
}
Example #2
0
/////////////////////////////////////////////////////////////////////////////
//! Connects to ENC28J60 chip
//! \return < 0 if initialisation sequence failed
//! \return -16 if clock not ready after system reset
//! \return -17 if unsupported revision ID
/////////////////////////////////////////////////////////////////////////////
s32 MIOS32_ENC28J60_PowerOn(void)
{
  s32 status;

  
  // deactivate chip select
  CSN_1;

  // ensure that fast pin drivers are activated
  MIOS32_SPI_IO_Init(MIOS32_ENC28J60_SPI, MIOS32_SPI_PIN_DRIVER_STRONG);

  // init SPI port for fast frequency access (ca. 18 MBit/s)
  if( (status=MIOS32_SPI_TransferModeInit(MIOS32_ENC28J60_SPI, MIOS32_SPI_MODE_CLK0_PHASE0, MIOS32_SPI_PRESCALER_4)) < 0 ) 
    return status;
  
  // send system reset command

  // RESET the entire ENC28J60, clearing all registers
  // Also wait for CLKRDY to become set.
  // Bit 3 in ESTAT is an unimplemented bit.  If it reads out as '1' that
  // means the part is in RESET or there is something wrong with the SPI 
  // connection.  This routine makes sure that we can communicate with the 
  // ENC28J60 before proceeding.
  if( (status=MIOS32_ENC28J60_SendSystemReset()) < 0 )
    return status;

  // check if chip is accessible (it should after ca. 1 mS)
  if( (status=MIOS32_ENC28J60_ReadETHReg(ESTAT)) < 0 )
    return status;

  if( (status & 0x08) || !(status & ESTAT_CLKRDY) )
    return -16; // no access to chip

  // read and check revision ID, this gives us another check if device is available
  MIOS32_ENC28J60_BankSel(EREVID);
  if( (status=MIOS32_ENC28J60_ReadMACReg((u8)EREVID)) < 0 )
    return status;

  rev_id = status;

  if( !rev_id || rev_id >= 32 ) {
    return -17; // unsupported revision ID
  }

  // Start up in Bank 0 and configure the receive buffer boundary pointers 
  // and the buffer write protect pointer (receive buffer read pointer)
  WasDiscarded = 1;
  NextPacketLocation = RXSTART;

  MIOS32_ENC28J60_BankSel(ERXSTL);
  status |= MIOS32_ENC28J60_WriteReg(ERXSTL,   (RXSTART) & 0xff);
  status |= MIOS32_ENC28J60_WriteReg(ERXSTH,   ((RXSTART) >> 8) & 0xff);
  status |= MIOS32_ENC28J60_WriteReg(ERXRDPTL, (RXSTOP) & 0xff);
  status |= MIOS32_ENC28J60_WriteReg(ERXRDPTH, ((RXSTOP) >> 8) & 0xff);
  status |= MIOS32_ENC28J60_WriteReg(ERXNDL,   (RXSTOP) & 0xff);
  status |= MIOS32_ENC28J60_WriteReg(ERXNDH,   ((RXSTOP) >> 8) & 0xff);
  status |= MIOS32_ENC28J60_WriteReg(ETXSTL,   (TXSTART) & 0xff);
  status |= MIOS32_ENC28J60_WriteReg(ETXSTH,   ((TXSTART) >> 8) & 0xff);

  // Write a permanant per packet control byte of 0x00
  status |= MIOS32_ENC28J60_WriteReg(EWRPTL,   (TXSTART) & 0xff);
  status |= MIOS32_ENC28J60_WriteReg(EWRPTH,   ((TXSTART) >> 8) & 0xff);
  status |= MIOS32_ENC28J60_MACPut(0x00);

  // Enter Bank 1 and configure Receive Filters 
  // (No need to reconfigure - Unicast OR Broadcast with CRC checking is 
  // acceptable)
  // Write ERXFCON_CRCEN only to ERXFCON to enter promiscuous mode

  // Promiscious mode example:
  // status |= MIOS32_ENC28J60_BankSel(ERXFCON);
  // status |= MIOS32_ENC28J60_WriteReg((u8)ERXFCON, ERXFCON_CRCEN);
        
  // Enter Bank 2 and configure the MAC
  status |= MIOS32_ENC28J60_BankSel(MACON1);

  // Enable the receive portion of the MAC
  status |= MIOS32_ENC28J60_WriteReg((u8)MACON1, MACON1_TXPAUS | MACON1_RXPAUS | MACON1_MARXEN);
        
  // Pad packets to 60 bytes, add CRC, and check Type/Length field.
#if MIOS32_ENC28J60_FULL_DUPLEX
  status |= MIOS32_ENC28J60_WriteReg((u8)MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN | MACON3_FULDPX);
  status |= MIOS32_ENC28J60_WriteReg((u8)MABBIPG, 0x15);  
#else
  status |= MIOS32_ENC28J60_WriteReg((u8)MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN);
  status |= MIOS32_ENC28J60_WriteReg((u8)MABBIPG, 0x12);  
#endif

  // Allow infinite deferals if the medium is continuously busy 
  // (do not time out a transmission if the half duplex medium is 
  // completely saturated with other people's data)
  status |= MIOS32_ENC28J60_WriteReg((u8)MACON4, MACON4_DEFER);

  // Late collisions occur beyond 63+8 bytes (8 bytes for preamble/start of frame delimiter)
  // 55 is all that is needed for IEEE 802.3, but ENC28J60 B5 errata for improper link pulse 
  // collisions will occur less often with a larger number.
  status |= MIOS32_ENC28J60_WriteReg((u8)MACLCON2, 63);
        
  // Set non-back-to-back inter-packet gap to 9.6us.  The back-to-back 
  // inter-packet gap (MABBIPG) is set by MACSetDuplex() which is called 
  // later.
  status |= MIOS32_ENC28J60_WriteReg((u8)MAIPGL, 0x12);
  status |= MIOS32_ENC28J60_WriteReg((u8)MAIPGH, 0x0C);

  // Set the maximum packet size which the controller will accept
  status |= MIOS32_ENC28J60_WriteReg((u8)MAMXFLL, (MIOS32_ENC28J60_MAX_FRAME_SIZE) & 0xff);
  status |= MIOS32_ENC28J60_WriteReg((u8)MAMXFLH, ((MIOS32_ENC28J60_MAX_FRAME_SIZE) >> 8) & 0xff);
        
  // initialize physical MAC address registers
  status |= MIOS32_ENC28J60_MAC_AddrSet(mac_addr);

  // Enter Bank 3 and Disable the CLKOUT output to reduce EMI generation
  status |= MIOS32_ENC28J60_BankSel(ECOCON);
  status |= MIOS32_ENC28J60_WriteReg((u8)ECOCON, 0x00);   // Output off (0V)
  //status |= MIOS32_ENC28J60_WriteReg((u8)ECOCON, 0x01); // 25.000MHz
  //status |= MIOS32_ENC28J60_WriteReg((u8)ECOCON, 0x03); // 8.3333MHz (*4 with PLL is 33.3333MHz)

  // Disable half duplex loopback in PHY.  Bank bits changed to Bank 2 as a 
  // side effect.
  status |= MIOS32_ENC28J60_WritePHYReg(PHCON2, PHCON2_HDLDIS);

  // Configure LEDA to display LINK status, LEDB to display TX/RX activity
  status |= MIOS32_ENC28J60_WritePHYReg(PHLCON, 0x3472);

  // Set the MAC and PHY into the proper duplex state
#if MIOS32_ENC28J60_FULL_DUPLEX
  status |= MIOS32_ENC28J60_WritePHYReg(PHCON1, PHCON1_PDPXMD);
#else
  status |= MIOS32_ENC28J60_WritePHYReg(PHCON1, 0x0000);
#endif
  status |= MIOS32_ENC28J60_BankSel(ERDPTL);                // Return to default Bank 0

  // Enable packet reception
  status |= MIOS32_ENC28J60_BFSReg(ECON1, ECON1_RXEN);

  return (status < 0) ? status : 0;
}
/////////////////////////////////////////////////////////////////////////////
//! Initializes SPI pins
//! \param[in] mode currently only mode 0 supported
//! \return < 0 if initialisation failed
/////////////////////////////////////////////////////////////////////////////
s32 MIOS32_SPI_Init(u32 mode)
{
  // currently only mode 0 supported
  if( mode != 0 )
    return -1; // unsupported mode

  DMA_InitTypeDef DMA_InitStructure;
  DMA_StructInit(&DMA_InitStructure);

  ///////////////////////////////////////////////////////////////////////////
  // SPI0
  ///////////////////////////////////////////////////////////////////////////
#ifndef MIOS32_DONT_USE_SPI0

  // disable callback function
  spi_callback[0] = NULL;

  // set RC pin(s) to 1
  MIOS32_SPI_RC_PinSet(0, 0, 1); // spi, rc_pin, pin_value
  MIOS32_SPI_RC_PinSet(0, 1, 1); // spi, rc_pin, pin_value

  // IO configuration
  MIOS32_SPI_IO_Init(0, MIOS32_SPI_PIN_DRIVER_WEAK_OD);

  // enable SPI peripheral clock (APB2 == high speed)
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

  // enable DMA1 clock
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  // DMA Configuration for SPI Rx Event
  DMA_Cmd(MIOS32_SPI0_DMA_RX_PTR, DISABLE);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&MIOS32_SPI0_PTR->DR;
  DMA_InitStructure.DMA_MemoryBaseAddr = 0; // will be configured later
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 0; // will be configured later
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(MIOS32_SPI0_DMA_RX_PTR, &DMA_InitStructure);

  // DMA Configuration for SPI Tx Event
  // (partly re-using previous DMA setup)
  DMA_Cmd(MIOS32_SPI0_DMA_TX_PTR, DISABLE);
  DMA_InitStructure.DMA_MemoryBaseAddr = 0; // will be configured later
  DMA_InitStructure.DMA_BufferSize = 0; // will be configured later
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_Init(MIOS32_SPI0_DMA_TX_PTR, &DMA_InitStructure);

  // enable SPI
  SPI_Cmd(MIOS32_SPI0_PTR, ENABLE);

  // enable SPI interrupts to DMA
  SPI_I2S_DMACmd(MIOS32_SPI0_PTR, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, ENABLE);

  // Configure DMA interrupt
  MIOS32_IRQ_Install(MIOS32_SPI0_DMA_IRQ_CHANNEL, MIOS32_IRQ_SPI_DMA_PRIORITY);

  // initial SPI peripheral configuration
  MIOS32_SPI_TransferModeInit(0, MIOS32_SPI_MODE_CLK1_PHASE1, MIOS32_SPI_PRESCALER_128);
#endif /* MIOS32_DONT_USE_SPI0 */


  ///////////////////////////////////////////////////////////////////////////
  // SPI1
  ///////////////////////////////////////////////////////////////////////////
#ifndef MIOS32_DONT_USE_SPI1

  // disable callback function
  spi_callback[1] = NULL;

  // set RC pin(s) to 1
  MIOS32_SPI_RC_PinSet(1, 0, 1); // spi, rc_pin, pin_value
  MIOS32_SPI_RC_PinSet(1, 1, 1); // spi, rc_pin, pin_value

  // IO configuration
  MIOS32_SPI_IO_Init(1, MIOS32_SPI_PIN_DRIVER_WEAK_OD);

  // enable SPI peripheral clock (APB1 == slow speed)
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

  // enable DMA1 clock
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  // DMA Configuration for SPI Rx Event
  DMA_Cmd(MIOS32_SPI1_DMA_RX_PTR, DISABLE);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&MIOS32_SPI1_PTR->DR;
  DMA_InitStructure.DMA_MemoryBaseAddr = 0; // will be configured later
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 0; // will be configured later
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(MIOS32_SPI1_DMA_RX_PTR, &DMA_InitStructure);

  // DMA Configuration for SPI Tx Event
  // (partly re-using previous DMA setup)
  DMA_Cmd(MIOS32_SPI1_DMA_TX_PTR, DISABLE);
  DMA_InitStructure.DMA_MemoryBaseAddr = 0; // will be configured later
  DMA_InitStructure.DMA_BufferSize = 0; // will be configured later
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_Init(MIOS32_SPI1_DMA_TX_PTR, &DMA_InitStructure);

  // enable SPI
  SPI_Cmd(MIOS32_SPI1_PTR, ENABLE);

  // enable SPI interrupts to DMA
  SPI_I2S_DMACmd(MIOS32_SPI1_PTR, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, ENABLE);

  // Configure DMA interrupt
  MIOS32_IRQ_Install(MIOS32_SPI1_DMA_IRQ_CHANNEL, MIOS32_IRQ_SPI_DMA_PRIORITY);

  // initial SPI peripheral configuration
  MIOS32_SPI_TransferModeInit(1, MIOS32_SPI_MODE_CLK1_PHASE1, MIOS32_SPI_PRESCALER_128);
#endif /* MIOS32_DONT_USE_SPI1 */


  ///////////////////////////////////////////////////////////////////////////
  // SPI2 (software emulated)
  ///////////////////////////////////////////////////////////////////////////
#ifndef MIOS32_DONT_USE_SPI2

  // disable callback function
  spi_callback[2] = NULL;

  // set RC pin(s) to 1
  MIOS32_SPI_RC_PinSet(2, 0, 1); // spi, rc_pin, pin_value
  MIOS32_SPI_RC_PinSet(2, 1, 1); // spi, rc_pin, pin_value

  // IO configuration
  MIOS32_SPI_IO_Init(2, MIOS32_SPI_PIN_DRIVER_WEAK_OD);

  // initial SPI peripheral configuration
  MIOS32_SPI_TransferModeInit(2, MIOS32_SPI_MODE_CLK1_PHASE1, MIOS32_SPI_PRESCALER_128);

#endif /* MIOS32_DONT_USE_SPI2 */

  return 0; // no error
}