Example #1
0
 /**
  * Assemble an iBeacon payload.
  *
  * @param[in] uuid Beacon network ID. iBeacon operators use this value
  * to group their iBeacons into a single network, a single region and
  * identify their organization among others.
  *
  * @param[in] majNum Beacon major group ID. iBeacon exploitants may use
  * this field to divide the region into subregions, their network into
  * subnetworks.
  *
  * @param[in] minNum Identifier of the Beacon in its subregion.
  *
  * @param[in] transmitPower Measured transmit power of the beacon at 1
  * meter. Scanners use this parameter to approximate the distance
  * to the beacon.
  *
  * @param[in] companyIDIn ID of the beacon manufacturer.
  */
 Payload(
     const uint8_t *uuid,
     uint16_t majNum,
     uint16_t minNum,
     uint8_t transmitPower,
     uint16_t companyIDIn
 ) : companyID(companyIDIn),
     ID(0x02),
     len(0x15),
     majorNumber(__REV16(majNum)),
     minorNumber(__REV16(minNum)),
     txPower(transmitPower)
 {
     memcpy(proximityUUID, uuid, 16);
 }
Example #2
0
File: sound.cpp Project: Kreyl/nute
// ================================ Inner use ==================================
void Sound_t::AddCmd(uint8_t AAddr, uint16_t AData) {
    VsCmd_t FCmd;
    FCmd.OpCode = VS_WRITE_OPCODE;
    FCmd.Address = AAddr;
    FCmd.Data = __REV16(AData);
    // Add cmd to queue
    chMBPost(&CmdBox, FCmd.Msg, TIME_INFINITE);
    StartTransmissionIfNotBusy();
}
Example #3
0
/***************************************************************************//**
 * @brief
 *   Perform a SCSI Write(10) command.
 *
 * @param[in] lba
 *   Sector address (LBA) of first sector to write.
 *
 * @param[in] sectors
 *   Number of sectors to write.
 *
 * @param[out] data
 *   Data buffer containing data to be written.
 *
 * @return
 *   Returns true on success, false otherwise.
 ******************************************************************************/
bool MSDSCSI_Write10(uint32_t lba, uint16_t sectors, const void *data)
{
  EFM32_ALIGN(4)
  MSDBOT_CBW_TypeDef cbw __attribute__ ((aligned(4))) = CBW_SCSI_WRITE10_INIT_DEFAULT;

  MSDSCSI_Write10_TypeDef *cb = (MSDSCSI_Write10_TypeDef*) &cbw.CBWCB;

  cbw.dCBWDataTransferLength = sectors * lbaSize;
  cb->Lba                    = __REV(lba);
  cb->TransferLength         = __REV16(sectors);

  if ((uint32_t) MSDBOT_Xfer(&cbw, (void*) data) == cbw.dCBWDataTransferLength)
    return true;

  return false;
}
Example #4
0
/**
  * @brief  Cal CRC16 for YModem Packet
  * @param  data
  * @param  length
  * @retval CRC value
  */
uint16_t Cal_CRC16(const uint8_t* data, uint32_t size)
{
  uint32_t crc = 0;
  const uint8_t* dataEnd = data+size;
  
#ifdef USE_CRC_PERIPH
  /* Reset CRC data register */
  CRC_ResetDR();
  while(data < dataEnd)
  {
    crc = CRC_CalcCRC16bits(__REV16(*(uint16_t *)data));
    data+=2;
  }
#else /* USE_CRC_SOFTWARE */
  while(data<dataEnd)
  {
    crc = UpdateCRC16(crc,*data++);
  }
  crc = UpdateCRC16(crc,0);
  crc = UpdateCRC16(crc,0);
#endif /* USE_CRC_PERIPH */
  return (crc&0xffffu);
}
/**************************************************************************//**
 * @brief
 *   Parse a SCSI command.
 *   A minimal, yet sufficient SCSI command subset is supported.
 *****************************************************************************/
static void ProcessScsiCdb(void)
{
  MSDSCSI_Inquiry_TypeDef      *cbI;
  MSDSCSI_RequestSense_TypeDef *cbRS;
  MSDSCSI_ReadCapacity_TypeDef *cbRC;
  MSDSCSI_Read10_TypeDef       *cbR10;
  MSDSCSI_Write10_TypeDef      *cbW10;

  EFM32_ALIGN(4)
  static MSDSCSI_ReadCapacityData_TypeDef ReadCapData __attribute__ ((aligned(4)));

  pCmdStatus->valid    = false;
  pCmdStatus->xferType = XFER_MEMORYMAPPED;
  pCmdStatus->maxBurst = MAX_BURST;

  switch (pCbw->CBWCB[ 0 ])
  {
  case SCSI_INQUIRY:
    cbI = (MSDSCSI_Inquiry_TypeDef*) &pCbw->CBWCB;

    if ((cbI->Evpd == 0) && (cbI->PageCode == 0))
    {
      /* Standard Inquiry data request */
      pCmdStatus->valid     = true;
      pCmdStatus->direction = DIR_DATA_IN;
      pCmdStatus->pData     = (uint8_t*) &InquiryData;
      pCmdStatus->xferLen   = EFM32_MIN(SCSI_INQUIRYDATA_LEN,
                                        __REV16(cbI->AllocationLength));
    }
    break;

  case SCSI_REQUESTSENSE:
    cbRS = (MSDSCSI_RequestSense_TypeDef*) &pCbw->CBWCB;

    if ((cbRS->Desc == 0) && (cbRS->Reserved1 == 0) &&
        (cbRS->Reserved2 == 0) && (cbRS->Reserved3 == 0))
    {
      pCmdStatus->valid     = true;
      pCmdStatus->direction = DIR_DATA_IN;
      pCmdStatus->pData     = (uint8_t*) pSenseData;
      pCmdStatus->xferLen   = EFM32_MIN(SCSI_REQUESTSENSEDATA_LEN,
                                        cbRS->AllocationLength);
      pSenseData = (MSDSCSI_RequestSenseData_TypeDef*) &NoSenseData;
    }
    break;

  case SCSI_READCAPACITY:
    cbRC = (MSDSCSI_ReadCapacity_TypeDef*) &pCbw->CBWCB;

    if ((cbRC->Pmi == 0) && (cbRC->Lba == 0))
    {
      ReadCapData.LogicalBlockAddress = __REV(MSDDMEDIA_GetSectorCount() - 1);
      ReadCapData.LogicalBlockLength  = __REV(512);

      pCmdStatus->valid     = true;
      pCmdStatus->direction = DIR_DATA_IN;
      pCmdStatus->pData     = (uint8_t*) &ReadCapData;
      pCmdStatus->xferLen   = SCSI_READCAPACITYDATA_LEN;
    }
    break;

  case SCSI_READ10:
    cbR10 = (MSDSCSI_Read10_TypeDef*) &pCbw->CBWCB;

    pCmdStatus->direction = DIR_DATA_IN;
    pCmdStatus->valid     = MSDDMEDIA_CheckAccess(pCmdStatus,
                                                  __REV(cbR10->Lba),
                                                  __REV16(cbR10->TransferLength));
    break;

  case SCSI_WRITE10:
    cbW10 = (MSDSCSI_Write10_TypeDef*) &pCbw->CBWCB;

    pCmdStatus->direction = DIR_DATA_OUT;
    pCmdStatus->valid     = MSDDMEDIA_CheckAccess(pCmdStatus,
                                                  __REV(cbW10->Lba),
                                                  __REV16(cbW10->TransferLength));
    break;

  case SCSI_TESTUNIT_READY:
    pCmdStatus->valid     = true;
    pCmdStatus->direction = pCbw->Direction;
    pCmdStatus->xferLen   = 0;
    break;

  case SCSI_STARTSTOP_UNIT:
    pCmdStatus->valid     = true;
    pCmdStatus->direction = pCbw->Direction;
    pCmdStatus->xferLen   = 0;
    pCmdStatus->xferType  = XFER_INDIRECT;
    break;
  }

  if (!pCmdStatus->valid)
  {
    pCmdStatus->xferLen   = 0;
    pCmdStatus->direction = pCbw->Direction;
    pSenseData            = (MSDSCSI_RequestSenseData_TypeDef*) &IllegalSenseData;
  }
}
Example #6
0
// TODO(rqou): Move this elsewhere
// TODO(rqou): This entire function is a hack
static portTASK_FUNCTION_PROTO(radioTask, pvParameters) {
  (void) pvParameters;

  // TODO(rqou): More intelligent interleaved
  uint32_t code_received_to = 0;
  uint32_t code_received_len = 0;
  int got_a_packet = 0;
  int should_harass = 0;
  const uint32_t CHUNK_SIZE = 64;
  // TODO(rqou): Hack
  uint8_t txbuf[64];
  // TODO(rqou): Ugly uglly
  uint64_t host_addr = 0;
  // TODO(rqou): Remove this (why does this crash anyways?)
  int started_angelic = 0;

  while (1) {
    uint8_t *buf;
    size_t len;

    if (!got_a_packet && should_harass) {
      // Harass host
      xbee_api_packet *packetOut = (xbee_api_packet *)(txbuf);
      packetOut->xbee_api_magic = XBEE_MAGIC;
      int payloadLen = sizeof(xbee_tx64_header) + sizeof(tenshi_bulk_chunkreq);
      packetOut->length = __REV16(payloadLen);
      packetOut->payload.tx64.xbee_api_type = XBEE_API_TYPE_TX64;
      packetOut->payload.tx64.frameId = 0;
      packetOut->payload.tx64.xbee_dest_addr = host_addr;
      packetOut->payload.tx64.options = 0;
      tenshi_bulk_chunkreq *bulk_chunkreq =
        (tenshi_bulk_chunkreq *)(packetOut->payload.tx64.data);
      bulk_chunkreq->ident = TENSHI_NAIVE_BULK_CHUNKREQ_IDENT;
      bulk_chunkreq->stream_id = 0;
      bulk_chunkreq->start_addr = code_received_to;
      if (code_received_to + CHUNK_SIZE > code_received_len) {
        bulk_chunkreq->end_addr = code_received_len;
      } else {
        bulk_chunkreq->end_addr = code_received_to + CHUNK_SIZE;
      }
      xbee_fill_checksum(packetOut);

      // TODO(rqou): Asynchronous?
      // TODO(rqou): Abstract away the +4 properly
      // TODO(rqou): Error handling
      void *txn = uart_serial_send_data(radio_driver, txbuf, payloadLen + 4);
      while ((uart_serial_send_status(radio_driver, txn) !=
          UART_SERIAL_SEND_DONE) &&
          (uart_serial_send_status(radio_driver, txn) !=
            UART_SERIAL_SEND_ERROR)) {}
      uart_serial_send_finish(radio_driver, txn);
    }
    got_a_packet = 0;

    buf = uart_serial_receive_packet(radio_driver, &len, 0);
    if (!buf) {
      // TODO(rqou): Proper timer, why the f*ck do I need to copy this here?
      vTaskDelay(20 / portTICK_RATE_MS);
      continue;
    }
    xbee_api_packet *packetIn = (xbee_api_packet *)buf;
    if (!xbee_verify_checksum(packetIn)) {
      vPortFree(buf);
      // TODO(rqou): Proper timer, why the f*ck do I need to copy this here?
      vTaskDelay(20 / portTICK_RATE_MS);
      continue;
    }
    if (packetIn->payload.xbee_api_type != XBEE_API_TYPE_RX64) {
      vPortFree(buf);
      // TODO(rqou): Proper timer, why the f*ck do I need to copy this here?
      vTaskDelay(20 / portTICK_RATE_MS);
      continue;
    }
    // ident byte for PiEMOS framing
    switch (packetIn->payload.rx64.data[0]) {
    case PIER_INCOMINGDATA_IDENT:
      {
        pier_incomingdata *incomingData =
          (pier_incomingdata *)(packetIn->payload.rx64.data);
        // TODO(rqou): This code is terribly hardcoded.
        for (int i = 0; i < 7; i++) {
          PiEMOSAnalogVals[i] =
            (float)((int)incomingData->analog[i] - 127) / 127.0f * 100.0f;
        }
        for (int i = 0; i < 8; i++) {
          PiEMOSDigitalVals[i] = !!(incomingData->digital & (1 << i));
        }
      }
      break;

    // Naive bulk protocol
    case TENSHI_NAIVE_BULK_START_IDENT:
      {
        tenshi_bulk_start *bulk_start =
          (tenshi_bulk_start *)(packetIn->payload.rx64.data);
        // TODO(rqou): What happens if I already have one?
        // TODO(rqou): Stream ID?
        code_buffer = pvPortMalloc(bulk_start->length);
        code_received_to = 0;
        code_buffer_len = code_received_len = bulk_start->length;
        got_a_packet = 1;
        should_harass = 1;

        // TODO(rqou): Refactor this logic
        host_addr = packetIn->payload.rx64.xbee_src_addr;
      }
      break;
    case TENSHI_NAIVE_BULK_CHUNK_IDENT:
      {
        tenshi_bulk_chunk *bulk_chunk =
          (tenshi_bulk_chunk *)(packetIn->payload.rx64.data);
        memcpy(code_buffer + bulk_chunk->start_addr, bulk_chunk->data,
          bulk_chunk->end_addr - bulk_chunk->start_addr);
        // TODO(rqou): Properly handle out-of-order
        code_received_to = bulk_chunk->end_addr;
        got_a_packet = 1;

        if (code_received_to == code_received_len) {
          xbee_api_packet *packetOut = (xbee_api_packet *)(txbuf);
          packetOut->xbee_api_magic = XBEE_MAGIC;
          int payloadLen = sizeof(xbee_tx64_header) + sizeof(tenshi_bulk_stop);
          packetOut->length = __REV16(payloadLen);
          packetOut->payload.tx64.xbee_api_type = XBEE_API_TYPE_TX64;
          packetOut->payload.tx64.frameId = 0;
          packetOut->payload.tx64.xbee_dest_addr =
            packetIn->payload.rx64.xbee_src_addr;
          packetOut->payload.tx64.options = 0;
          tenshi_bulk_stop *bulk_stop =
            (tenshi_bulk_stop *)(packetOut->payload.tx64.data);
          bulk_stop->ident = TENSHI_NAIVE_BULK_STOP_IDENT;
          bulk_stop->stream_id = 0;
          xbee_fill_checksum(packetOut);

          should_harass = 0;

          // TODO(rqou): Asynchronous?
          // TODO(rqou): Abstract away the +4 properly
          // TODO(rqou): Error handling
          void *txn =
            uart_serial_send_data(radio_driver, txbuf, payloadLen + 4);
          while ((uart_serial_send_status(radio_driver, txn) !=
              UART_SERIAL_SEND_DONE) &&
              (uart_serial_send_status(radio_driver, txn) !=
                UART_SERIAL_SEND_ERROR)) {}
          uart_serial_send_finish(radio_driver, txn);

          if (!started_angelic) {
            started_angelic = 1;
            xTaskCreate(angelicTask, "Angelic", 2048, NULL,
              tskIDLE_PRIORITY, NULL);
          }
        }
      }
      break;

    default:
      // TODO(rqou): Report error or something?
      break;
    }

    vPortFree(buf);

    // TODO(rqou): Proper timer
    vTaskDelay(20 / portTICK_RATE_MS);
  }
}
extern void application_task(void)
{
  UINT bytesread = 0;
  WAVE_FormatTypeDef waveformat;
  
  switch (appState)
  {
    case APPSTATE_IDLE:
      if (usbConnected)
      {
        appState = APPSTATE_MOUNT_FS;
      }
      break;
    
    case APPSTATE_GEN_SINE:
      waveformat.SampleRate = SINE_GEN_AUDIO_SAMPLE_RATE;
      waveformat.FileSize = SINE_GEN_AUDIO_SAMPLE_RATE * SINE_GEN_DURATION * \
                            sizeof(int16_t) + sizeof(WAVE_FormatTypeDef);
      waveformat.NbrChannels = CHANNEL_MONO;
      WavePlayerStart(waveformat, getDataSineCB, 70);
      break;
    
    case APPSTATE_MOUNT_FS:
      if (f_mount(&USBDISKFatFs, (TCHAR const*)USBDISKPath, 0 ) != FR_OK ) 
      {
        /* FatFs initialization fails */
        Error_Handler();
      }
      else
      {
        appState = APPSTATE_WRITE;
      }
      break;
    
    case APPSTATE_UMOUNT_FS:
      f_mount(NULL, (TCHAR const*)"", 1);
      appState = APPSTATE_IDLE;
      break;
    
    case APPSTATE_WRITE:
      if (f_open(&FileWrite, WAVE_NAME_COMPLETO, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
      {
        Error_Handler();
      }
      else
      {
        waveformat.SampleRate = SINE_GEN_AUDIO_SAMPLE_RATE;
        waveformat.FileSize = SINE_GEN_AUDIO_SAMPLE_RATE * SINE_GEN_DURATION * \
                              sizeof(int16_t) + sizeof(WAVE_FormatTypeDef);
        waveformat.NbrChannels = WAVE_CHANNEL_MONO;
        waveformat.ByteRate = SINE_GEN_AUDIO_SAMPLE_RATE * WAVE_CHANNEL_MONO * sizeof(int16_t);
        waveformat.BitPerSample = __REV16(WAVE_16_BIT_PER_SAMPLE);
        waveformat.SubChunk2Size = SINE_GEN_AUDIO_SAMPLE_RATE * SINE_GEN_DURATION * sizeof(int16_t);
      
        WaveRecord(&FileWrite, waveformat, getDataSineCB);
        f_close(&FileWrite);
        appState = APPSTATE_PLAY;
      }
      break;

    case APPSTATE_PLAY:
      if (f_open(&FileRead, WAVE_NAME_COMPLETO, FA_READ) != FR_OK)
      {
        Error_Handler();
      }
      else
      {
        /* Read sizeof(WaveFormat) from the selected file */
        f_read (&FileRead, &waveformat, sizeof(waveformat), &bytesread);
        WavePlayerStart(waveformat, getDataCB, 70);
        f_close(&FileRead);
      }
      break;
    
    default:
      appState = APPSTATE_IDLE;
      break;
  }
}