From 5a059c8d6ecfe2f98a77570b8b6cf13c500398f7 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Fri, 11 Nov 2016 15:15:16 -0500 Subject: tar'd chibi --- .../community/os/hal/src/hal_community.c | 87 -- ChibiOS_16.1.5/community/os/hal/src/hal_crc.c | 264 ---- ChibiOS_16.1.5/community/os/hal/src/hal_ee24xx.c | 353 ----- ChibiOS_16.1.5/community/os/hal/src/hal_ee25xx.c | 404 ------ ChibiOS_16.1.5/community/os/hal/src/hal_eeprom.c | 197 --- ChibiOS_16.1.5/community/os/hal/src/hal_eicu.c | 153 --- ChibiOS_16.1.5/community/os/hal/src/hal_nand.c | 567 -------- ChibiOS_16.1.5/community/os/hal/src/hal_onewire.c | 890 ------------- ChibiOS_16.1.5/community/os/hal/src/hal_qei.c | 214 --- ChibiOS_16.1.5/community/os/hal/src/hal_rng.c | 182 --- ChibiOS_16.1.5/community/os/hal/src/hal_timcap.c | 159 --- ChibiOS_16.1.5/community/os/hal/src/hal_usb_hid.c | 581 -------- ChibiOS_16.1.5/community/os/hal/src/hal_usbh.c | 1395 -------------------- .../community/os/hal/src/usbh/hal_usbh_debug.c | 536 -------- .../community/os/hal/src/usbh/hal_usbh_desciter.c | 165 --- .../community/os/hal/src/usbh/hal_usbh_ftdi.c | 717 ---------- .../community/os/hal/src/usbh/hal_usbh_hub.c | 302 ----- .../community/os/hal/src/usbh/hal_usbh_msd.c | 939 ------------- .../community/os/hal/src/usbh/hal_usbh_uvc.c | 89 -- 19 files changed, 8194 deletions(-) delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/hal_community.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/hal_crc.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/hal_ee24xx.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/hal_ee25xx.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/hal_eeprom.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/hal_eicu.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/hal_nand.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/hal_onewire.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/hal_qei.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/hal_rng.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/hal_timcap.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/hal_usb_hid.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/hal_usbh.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_debug.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_desciter.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_ftdi.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_hub.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_msd.c delete mode 100644 ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_uvc.c (limited to 'ChibiOS_16.1.5/community/os/hal/src') diff --git a/ChibiOS_16.1.5/community/os/hal/src/hal_community.c b/ChibiOS_16.1.5/community/os/hal/src/hal_community.c deleted file mode 100644 index 8a39bf1..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/hal_community.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2014 Uladzimir Pylinsky aka barthess - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/** - * @file hal_community.c - * @brief HAL subsystem code. - * - * @addtogroup HAL - * @{ - */ - -#include "hal.h" - -#if (HAL_USE_COMMUNITY == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief HAL initialization (community part). - * - * @init - */ -void halCommunityInit(void) { - -#if HAL_USE_NAND || defined(__DOXYGEN__) - nandInit(); -#endif - -#if HAL_USE_EICU || defined(__DOXYGEN__) - eicuInit(); -#endif - -#if HAL_USE_CRC || defined(__DOXYGEN__) - crcInit(); -#endif - -#if HAL_USE_RNG || defined(__DOXYGEN__) - rngInit(); -#endif - -#if HAL_USE_USBH || defined(__DOXYGEN__) - usbhInit(); -#endif - -#if HAL_USE_TIMCAP || defined(__DOXYGEN__) - timcapInit(); -#endif - -#if HAL_USE_QEI || defined(__DOXYGEN__) - qeiInit(); -#endif -} - -#endif /* HAL_USE_COMMUNITY */ - -/** @} */ diff --git a/ChibiOS_16.1.5/community/os/hal/src/hal_crc.c b/ChibiOS_16.1.5/community/os/hal/src/hal_crc.c deleted file mode 100644 index 63799e4..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/hal_crc.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - ChibiOS - Copyright (C) 2015 Michael D. Spradling - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/* - * Hardware Abstraction Layer for CRC Unit - */ -#include "hal.h" - -#if (HAL_USE_CRC == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief CRC Driver initialization. - * - * @init - */ -void crcInit(void) { - crc_lld_init(); -} - -/** - * @brief Initializes the standard part of a @p CRCDriver structure. - * - * @param[out] crcp Pointer to the @p CRCDriver object - * - * @init - */ -void crcObjectInit(CRCDriver *crcp) { - crcp->state = CRC_STOP; - crcp->config = NULL; -#if CRC_USE_DMA == TRUE - crcp->thread = NULL; -#endif -#if CRC_USE_MUTUAL_EXCLUSION == TRUE - osalMutexObjectInit(&crcp->mutex); -#endif -#if defined(CRC_DRIVER_EXT_INIT_HOOK) - CRC_DRIVER_EXT_INIT_HOOK(crcp); -#endif -} - -/** - * @brief Configures and activates the CRC peripheral. - * - * @param[in] crcp Pointer to the @p CRCDriver object - * @param[in] config Pointer to the @p CRCConfig object - * @p NULL if the low level driver implementation - * supports a default configuration - * - * @api - */ -void crcStart(CRCDriver *crcp, const CRCConfig *config) { - osalDbgCheck(crcp != NULL); - - osalSysLock(); - osalDbgAssert((crcp->state == CRC_STOP) || (crcp->state == CRC_READY), - "invalid state"); - crcp->config = config; - crc_lld_start(crcp); - crcp->state = CRC_READY; - osalSysUnlock(); -} - -/** - * @brief Deactivates the CRC peripheral. - * - * @param[in] crcp Pointer to the @p CRCDriver object - * - * @api - */ -void crcStop(CRCDriver *crcp) { - osalDbgCheck(crcp != NULL); - - osalSysLock(); - osalDbgAssert((crcp->state == CRC_STOP) || (crcp->state == CRC_READY), - "invalid state"); - crc_lld_stop(crcp); - crcp->state = CRC_STOP; - osalSysUnlock(); -} - -/** - * @brief Resets the CRC calculation - * - * @param[in] crcp Pointer to the @p CRCDriver object - * - * @api - */ -void crcReset(CRCDriver *crcp) { - osalSysLock(); - crcResetI(crcp); - osalSysUnlock(); -} - -/** - * @brief Resets the current CRC calculation - * - * @param[in] crcp pointer to the @p CRCDriver object - * - * @iclass - */ -void crcResetI(CRCDriver *crcp) { - osalDbgCheck(crcp != NULL); - osalDbgAssert(crcp->state == CRC_READY, "Not ready"); - crc_lld_reset(crcp); -} - -/** - * @brief Performs a CRC calculation. - * @details This synchronous function performs a crc calculation operation. - * @pre In order to use this function the driver must have been configured - * without callbacks (@p end_cb = @p NULL). - * - * @param[in] crcp pointer to the @p CRCDriver object - * @param[in] n number of bytes to send - * @param[in] buf the pointer to the buffer - * - * @api - */ -uint32_t crcCalc(CRCDriver *crcp, size_t n, const void *buf) { - uint32_t crc; -#if CRC_USE_DMA - osalSysLock(); -#endif - crc = crcCalcI(crcp, n, buf); -#if CRC_USE_DMA - osalSysUnlock(); -#endif - return crc; -} - -/** - * @brief Performs a CRC calculation. - * @details This synchronous function performs a crc calcuation operation. - * @pre In order to use this function the driver must have been configured - * without callbacks (@p end_cb = @p NULL). - * @post At the end of the operation the configured callback is invoked. - * - * @param[in] crcp pointer to the @p CRCDriver object - * @param[in] n number of bytes to send - * @param[in] buf the pointer to the buffer - * - * @iclass - */ -uint32_t crcCalcI(CRCDriver *crcp, size_t n, const void *buf) { - osalDbgCheck((crcp != NULL) && (n > 0U) && (buf != NULL)); - osalDbgAssert(crcp->state == CRC_READY, "not ready"); -#if CRC_USE_DMA - osalDbgAssert(crcp->config->end_cb == NULL, "callback defined"); - (crcp)->state = CRC_ACTIVE; -#endif - return crc_lld_calc(crcp, n, buf); -} - -#if CRC_USE_DMA == TRUE -/** - * @brief Performs a CRC calculation. - * @details This asynchronous function starts a crc calcuation operation. - * @pre In order to use this function the driver must have been configured - * with callbacks (@p end_cb != @p NULL). - * @post At the end of the operation the configured callback is invoked. - * - * @param[in] crcp pointer to the @p CRCDriver object - * @param[in] n number of bytes to send - * @param[in] buf the pointer to the buffer - * - * @api - */ -void crcStartCalc(CRCDriver *crcp, size_t n, const void *buf) { - osalSysLock(); - crcStartCalcI(crcp, n, buf); - osalSysUnlock(); -} - -/** - * @brief Performs a CRC calculation. - * @details This asynchronous function starts a crc calcuation operation. - * @pre In order to use this function the driver must have been configured - * without callbacks (@p end_cb = @p NULL). - * @post At the end of the operation the configured callback is invoked. - * - * @param[in] crcp pointer to the @p CRCDriver object - * @param[in] n number of bytes to send - * @param[in] buf the pointer to the buffer - * - * - * @iclass - */ -void crcStartCalcI(CRCDriver *crcp, size_t n, const void *buf) { - osalDbgCheck((crcp != NULL) && (n > 0U) && (buf != NULL)); - osalDbgAssert(crcp->state == CRC_READY, "not ready"); - osalDbgAssert(crcp->config->end_cb != NULL, "callback not defined"); - (crcp)->state = CRC_ACTIVE; - crc_lld_start_calc(crcp, n, buf); -} -#endif - -#if (CRC_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__) -/** - * @brief Gains exclusive access to the CRC unit. - * @details This function tries to gain ownership to the CRC, if the CRC is - * already being used then the invoking thread is queued. - * @pre In order to use this function the option @p CRC_USE_MUTUAL_EXCLUSION - * must be enabled. - * - * @param[in] crcp pointer to the @p CRCDriver object - * - * @api - */ -void crcAcquireUnit(CRCDriver *crcp) { - osalDbgCheck(crcp != NULL); - - osalMutexLock(&crcp->mutex); -} - -/** - * @brief Releases exclusive access to the CRC unit. - * @pre In order to use this function the option @p CRC_USE_MUTUAL_EXCLUSION - * must be enabled. - * - * @param[in] crcp pointer to the @p CRCDriver object - * - * @api - */ -void crcReleaseUnit(CRCDriver *crcp) { - osalDbgCheck(crcp != NULL); - - osalMutexUnlock(&crcp->mutex); -} -#endif /* CRC_USE_MUTUAL_EXCLUSION == TRUE */ - -#endif /* HAL_USE_CRC */ diff --git a/ChibiOS_16.1.5/community/os/hal/src/hal_ee24xx.c b/ChibiOS_16.1.5/community/os/hal/src/hal_ee24xx.c deleted file mode 100644 index 632ffbb..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/hal_ee24xx.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - Copyright (c) 2013 Timon Wong - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -/* - Copyright 2012 Uladzimir Pylinski aka barthess. - You may use this work without restrictions, as long as this notice is included. - The work is provided "as is" without warranty of any kind, neither express nor implied. -*/ - -/***************************************************************************** - * DATASHEET NOTES - ***************************************************************************** -Write cycle time (byte or page) - 5 ms - -Note: - Page write operations are limited to writing bytes within a single physical - page, regardless of the number of bytes actually being written. Physical page - boundaries start at addresses that are integer multiples of the page buffer - size (or page size and end at addresses that are integer multiples of - [page size]. If a Page Write command attempts to write across a physical - page boundary, the result is that the data wraps around to the beginning of - the current page (overwriting data previously stored there), instead of - being written to the next page as might be expected. -*********************************************************************/ - -#include "hal_ee24xx.h" -#include - -#if (defined(HAL_USE_EEPROM) && HAL_USE_EEPROM && EEPROM_USE_EE24XX) || defined(__DOXYGEN__) - -/* - ****************************************************************************** - * DEFINES - ****************************************************************************** - */ -/* -#if defined(SAM7_PLATFORM) -#define EEPROM_I2C_CLOCK (MCK / (((i2cp->config->cwgr & 0xFF) + ((i2cp->config->cwgr >> 8) & 0xFF)) * (1 << ((i2cp->config->cwgr >> 16) & 7)) + 6)) -#else -#define EEPROM_I2C_CLOCK (i2cp->config->clock_speed) -#endif -*/ -#define EEPROM_I2C_CLOCK 400000 - -/* - ****************************************************************************** - * EXTERNS - ****************************************************************************** - */ - -/* - ****************************************************************************** - * GLOBAL VARIABLES - ****************************************************************************** - */ - -/* - ******************************************************************************* - * LOCAL FUNCTIONS - ******************************************************************************* - */ -/** - * @brief Split one uint16_t address to two uint8_t. - * - * @param[in] txbuf pointer to driver transmit buffer - * @param[in] addr uint16_t address - */ -#define eeprom_split_addr(txbuf, addr){ \ - (txbuf)[0] = ((uint8_t)((addr >> 8) & 0xFF)); \ - (txbuf)[1] = ((uint8_t)(addr & 0xFF)); \ - } - -/* - ******************************************************************************* - * EXPORTED FUNCTIONS - ******************************************************************************* - */ - -/** - * @brief Calculates requred timeout. - */ -static systime_t calc_timeout(I2CDriver *i2cp, size_t txbytes, size_t rxbytes) { - (void)i2cp; - const uint32_t bitsinbyte = 10; - uint32_t tmo; - tmo = ((txbytes + rxbytes + 1) * bitsinbyte * 1000); - tmo /= EEPROM_I2C_CLOCK; - tmo += 10; /* some additional milliseconds to be safer */ - return MS2ST(tmo); -} - -/** - * @brief EEPROM read routine. - * - * @param[in] eepcfg pointer to configuration structure of eeprom file - * @param[in] offset addres of 1-st byte to be read - * @param[in] data pointer to buffer with data to be written - * @param[in] len number of bytes to be red - */ -static msg_t eeprom_read(const I2CEepromFileConfig *eepcfg, - uint32_t offset, uint8_t *data, size_t len) { - - msg_t status = MSG_RESET; - systime_t tmo = calc_timeout(eepcfg->i2cp, 2, len); - - osalDbgAssert(((len <= eepcfg->size) && ((offset + len) <= eepcfg->size)), - "out of device bounds"); - - eeprom_split_addr(eepcfg->write_buf, (offset + eepcfg->barrier_low)); - -#if I2C_USE_MUTUAL_EXCLUSION - i2cAcquireBus(eepcfg->i2cp); -#endif - - status = i2cMasterTransmitTimeout(eepcfg->i2cp, eepcfg->addr, - eepcfg->write_buf, 2, data, len, tmo); - -#if I2C_USE_MUTUAL_EXCLUSION - i2cReleaseBus(eepcfg->i2cp); -#endif - - return status; -} - -/** - * @brief EEPROM write routine. - * @details Function writes data to EEPROM. - * @pre Data must be fit to single EEPROM page. - * - * @param[in] eepcfg pointer to configuration structure of eeprom file - * @param[in] offset addres of 1-st byte to be write - * @param[in] data pointer to buffer with data to be written - * @param[in] len number of bytes to be written - */ -static msg_t eeprom_write(const I2CEepromFileConfig *eepcfg, uint32_t offset, - const uint8_t *data, size_t len) { - msg_t status = MSG_RESET; - systime_t tmo = calc_timeout(eepcfg->i2cp, (len + 2), 0); - - osalDbgAssert(((len <= eepcfg->size) && ((offset + len) <= eepcfg->size)), - "out of device bounds"); - osalDbgAssert((((offset + eepcfg->barrier_low) / eepcfg->pagesize) == - (((offset + eepcfg->barrier_low) + len - 1) / eepcfg->pagesize)), - "data can not be fitted in single page"); - - /* write address bytes */ - eeprom_split_addr(eepcfg->write_buf, (offset + eepcfg->barrier_low)); - /* write data bytes */ - memcpy(&(eepcfg->write_buf[2]), data, len); - -#if I2C_USE_MUTUAL_EXCLUSION - i2cAcquireBus(eepcfg->i2cp); -#endif - - status = i2cMasterTransmitTimeout(eepcfg->i2cp, eepcfg->addr, - eepcfg->write_buf, (len + 2), NULL, 0, tmo); - -#if I2C_USE_MUTUAL_EXCLUSION - i2cReleaseBus(eepcfg->i2cp); -#endif - - /* wait until EEPROM process data */ - chThdSleep(eepcfg->write_time); - - return status; -} - -/** - * @brief Determines and returns size of data that can be processed - */ -static size_t __clamp_size(void *ip, size_t n) { - - if (((size_t)eepfs_getposition(ip) + n) > (size_t)eepfs_getsize(ip)) - return eepfs_getsize(ip) - eepfs_getposition(ip); - else - return n; -} - -/** - * @brief Write data that can be fitted in one page boundary - */ -static void __fitted_write(void *ip, const uint8_t *data, size_t len, uint32_t *written) { - - msg_t status = MSG_RESET; - - osalDbgAssert(len != 0, "something broken in hi level part"); - - status = eeprom_write(((I2CEepromFileStream *)ip)->cfg, - eepfs_getposition(ip), data, len); - if (status == MSG_OK) { - *written += len; - eepfs_lseek(ip, eepfs_getposition(ip) + len); - } -} - -/** - * @brief Write data to EEPROM. - * @details Only one EEPROM page can be written at once. So fucntion - * splits large data chunks in small EEPROM transactions if needed. - * @note To achieve the maximum effectivity use write operations - * aligned to EEPROM page boundaries. - */ -static size_t write(void *ip, const uint8_t *bp, size_t n) { - - size_t len = 0; /* bytes to be written at one trasaction */ - uint32_t written; /* total bytes successfully written */ - uint16_t pagesize; - uint32_t firstpage; - uint32_t lastpage; - - osalDbgCheck((ip != NULL) && (((EepromFileStream *)ip)->vmt != NULL)); - - if (n == 0) - return 0; - - n = __clamp_size(ip, n); - if (n == 0) - return 0; - - pagesize = ((EepromFileStream *)ip)->cfg->pagesize; - firstpage = (((EepromFileStream *)ip)->cfg->barrier_low + - eepfs_getposition(ip)) / pagesize; - lastpage = (((EepromFileStream *)ip)->cfg->barrier_low + - eepfs_getposition(ip) + n - 1) / pagesize; - - written = 0; - /* data fitted in single page */ - if (firstpage == lastpage) { - len = n; - __fitted_write(ip, bp, len, &written); - bp += len; - return written; - } - - else { - /* write first piece of data to first page boundary */ - len = ((firstpage + 1) * pagesize) - eepfs_getposition(ip); - len -= ((EepromFileStream *)ip)->cfg->barrier_low; - __fitted_write(ip, bp, len, &written); - bp += len; - - /* now writes blocks at a size of pages (may be no one) */ - while ((n - written) > pagesize) { - len = pagesize; - __fitted_write(ip, bp, len, &written); - bp += len; - } - - /* wrtie tail */ - len = n - written; - if (len == 0) - return written; - else { - __fitted_write(ip, bp, len, &written); - } - } - - return written; -} - -/** - * Read some bytes from current position in file. After successful - * read operation the position pointer will be increased by the number - * of read bytes. - */ -static size_t read(void *ip, uint8_t *bp, size_t n) { - msg_t status = MSG_OK; - - osalDbgCheck((ip != NULL) && (((EepromFileStream *)ip)->vmt != NULL)); - - if (n == 0) - return 0; - - n = __clamp_size(ip, n); - if (n == 0) - return 0; - - /* Stupid I2C cell in STM32F1x does not allow to read single byte. - So we must read 2 bytes and return needed one. */ -#if defined(STM32F1XX_I2C) - if (n == 1) { - uint8_t __buf[2]; - /* if NOT last byte of file requested */ - if ((eepfs_getposition(ip) + 1) < eepfs_getsize(ip)) { - if (read(ip, __buf, 2) == 2) { - eepfs_lseek(ip, (eepfs_getposition(ip) + 1)); - bp[0] = __buf[0]; - return 1; - } - else - return 0; - } - else { - eepfs_lseek(ip, (eepfs_getposition(ip) - 1)); - if (read(ip, __buf, 2) == 2) { - eepfs_lseek(ip, (eepfs_getposition(ip) + 2)); - bp[0] = __buf[1]; - return 1; - } - else - return 0; - } - } -#endif /* defined(STM32F1XX_I2C) */ - - /* call low level function */ - status = eeprom_read(((I2CEepromFileStream *)ip)->cfg, - eepfs_getposition(ip), bp, n); - if (status != MSG_OK) - return 0; - else { - eepfs_lseek(ip, (eepfs_getposition(ip) + n)); - return n; - } -} - -static const struct EepromFileStreamVMT vmt = { - write, - read, - eepfs_put, - eepfs_get, - eepfs_close, - eepfs_geterror, - eepfs_getsize, - eepfs_getposition, - eepfs_lseek, -}; - -EepromDevice eepdev_24xx = { - EEPROM_DEV_24XX, - &vmt -}; - -#endif /* EEPROM_USE_EE24XX */ diff --git a/ChibiOS_16.1.5/community/os/hal/src/hal_ee25xx.c b/ChibiOS_16.1.5/community/os/hal/src/hal_ee25xx.c deleted file mode 100644 index 102aef8..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/hal_ee25xx.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - Copyright (c) 2013 Timon Wong - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -/* - Copyright 2012 Uladzimir Pylinski aka barthess. - You may use this work without restrictions, as long as this notice is included. - The work is provided "as is" without warranty of any kind, neither express nor implied. -*/ - -/***************************************************************************** - * DATASHEET NOTES - ***************************************************************************** -Write cycle time (byte or page) - 5 ms - -Note: - Page write operations are limited to writing bytes within a single physical - page, regardless of the number of bytes actually being written. Physical page - boundaries start at addresses that are integer multiples of the page buffer - size (or page size and end at addresses that are integer multiples of - [page size]. If a Page Write command attempts to write across a physical - page boundary, the result is that the data wraps around to the beginning of - the current page (overwriting data previously stored there), instead of - being written to the next page as might be expected. -*********************************************************************/ - -#include "hal_ee25xx.h" -#include - -#if (defined(HAL_USE_EEPROM) && HAL_USE_EEPROM && EEPROM_USE_EE25XX) || defined(__DOXYGEN__) - -/** - * @name Commands of 25XX chip. - * @{ - */ -#define CMD_READ 0x03 /**< @brief Read data from memory array beginning at - selected address. */ -#define CMD_WRITE 0x02 /**< @brief Write data to memory array beginning at - selected address. */ -#define CMD_WRDI 0x04 /**< Reset the write enable latch (disable write - operations). */ -#define CMD_WREN 0x06 /**< Set the write enable latch (enable write - operations). */ -#define CMD_RDSR 0x05 /**< Read STATUS register. */ -#define CMD_WRSR 0x01 /**< Write STATUS register. */ - -/** @} */ - -/** - * @name Status of 25XX chip. - * @{} - */ -#define STAT_BP1 0x08 /**< @brief Block protection (high). */ -#define STAT_BP0 0x04 /**< @brief Block protection (low). */ -#define STAT_WEL 0x02 /**< @brief Write enable latch. */ -#define STAT_WIP 0x01 /**< @brief Write-In-Progress. */ - -/** @} */ - -/** - * @brief 25XX low level write then read rountine. - * - * @param[in] eepcfg pointer to configuration structure of eeprom file. - * @param[in] txbuf pointer to buffer to be transfered. - * @param[in] txlen number of bytes to be transfered. - * @param[out] rxbuf pointer to buffer to be received. - * @param[in] rxlen number of bytes to be received. - */ -static void ll_25xx_transmit_receive(const SPIEepromFileConfig *eepcfg, - const uint8_t *txbuf, size_t txlen, - uint8_t *rxbuf, size_t rxlen) { - -#if SPI_USE_MUTUAL_EXCLUSION - spiAcquireBus(eepcfg->spip); -#endif - spiSelect(eepcfg->spip); - spiSend(eepcfg->spip, txlen, txbuf); - if (rxlen) /* Check if receive is needed. */ - spiReceive(eepcfg->spip, rxlen, rxbuf); - spiUnselect(eepcfg->spip); - -#if SPI_USE_MUTUAL_EXCLUSION - spiReleaseBus(eepcfg->spip); -#endif -} - -/** - * @brief Check whether the device is busy (writing in progress). - * - * @param[in] eepcfg pointer to configuration structure of eeprom file. - * @return @p true on busy. - */ -static bool ll_eeprom_is_busy(const SPIEepromFileConfig *eepcfg) { - - uint8_t cmd = CMD_RDSR; - uint8_t stat; - ll_25xx_transmit_receive(eepcfg, &cmd, 1, &stat, 1); - if (stat & STAT_WIP) - return TRUE; - return FALSE; -} - -/** - * @brief Lock device. - * - * @param[in] eepcfg pointer to configuration structure of eeprom file. - */ -static void ll_eeprom_lock(const SPIEepromFileConfig *eepcfg) { - - uint8_t cmd = CMD_WRDI; - ll_25xx_transmit_receive(eepcfg, &cmd, 1, NULL, 0); -} - -/** - * @brief Unlock device. - * - * @param[in] eepcfg pointer to configuration structure of eeprom file. - */ -static void ll_eeprom_unlock(const SPIEepromFileConfig *eepcfg) { - - uint8_t cmd = CMD_WREN; - ll_25xx_transmit_receive(eepcfg, &cmd, 1, NULL, 0); -} - -/** - * @brief Prepare byte sequence for command and address - * - * @param[in] seq pointer to first 3byte sequence - * @param[in] size size of the eeprom device - * @param[in] cmd command - * @param[in] addr address - * @return number of bytes of this sequence - */ -static uint8_t ll_eeprom_prepare_seq(uint8_t *seq, uint32_t size, uint8_t cmd, - uint32_t addr) { - - seq[0] = ((uint8_t)cmd & 0xff); - - if (size > 0xffffUL) { - /* High density, 24bit address. */ - seq[1] = (uint8_t)((addr >> 16) & 0xff); - seq[2] = (uint8_t)((addr >> 8) & 0xff); - seq[3] = (uint8_t)(addr & 0xff); - return 4; - } - else if (size > 0x00ffUL) { - /* Medium density, 16bit address. */ - seq[1] = (uint8_t)((addr >> 8) & 0xff); - seq[2] = (uint8_t)(addr & 0xff); - return 3; - } - - /* Low density, 8bit address. */ - seq[1] = (uint8_t)(addr & 0xff); - return 2; -} - -/** - * @brief EEPROM read routine. - * - * @param[in] eepcfg pointer to configuration structure of eeprom file. - * @param[in] offset addres of 1-st byte to be read. - * @param[out] data pointer to buffer with data to be written. - * @param[in] len number of bytes to be red. - */ -static msg_t ll_eeprom_read(const SPIEepromFileConfig *eepcfg, uint32_t offset, - uint8_t *data, size_t len) { - - uint8_t txbuff[4]; - uint8_t txlen; - - osalDbgAssert(((len <= eepcfg->size) && ((offset + len) <= eepcfg->size)), - "out of device bounds"); - - if (eepcfg->spip->state != SPI_READY) - return MSG_RESET; - - txlen = ll_eeprom_prepare_seq(txbuff, eepcfg->size, CMD_READ, - (offset + eepcfg->barrier_low)); - ll_25xx_transmit_receive(eepcfg, txbuff, txlen, data, len); - - return MSG_OK; -} - -/** - * @brief EEPROM write routine. - * @details Function writes data to EEPROM. - * @pre Data must be fit to single EEPROM page. - * - * @param[in] eepcfg pointer to configuration structure of eeprom file. - * @param[in] offset addres of 1-st byte to be writen. - * @param[in] data pointer to buffer with data to be written. - * @param[in] len number of bytes to be written. - */ -static msg_t ll_eeprom_write(const SPIEepromFileConfig *eepcfg, uint32_t offset, - const uint8_t *data, size_t len) { - - uint8_t txbuff[4]; - uint8_t txlen; - systime_t now; - - osalDbgAssert(((len <= eepcfg->size) && ((offset + len) <= eepcfg->size)), - "out of device bounds"); - osalDbgAssert((((offset + eepcfg->barrier_low) / eepcfg->pagesize) == - (((offset + eepcfg->barrier_low) + len - 1) / eepcfg->pagesize)), - "data can not be fitted in single page"); - - if (eepcfg->spip->state != SPI_READY) - return MSG_RESET; - - /* Unlock array for writting. */ - ll_eeprom_unlock(eepcfg); - -#if SPI_USE_MUTUAL_EXCLUSION - spiAcquireBus(eepcfg->spip); -#endif - - spiSelect(eepcfg->spip); - txlen = ll_eeprom_prepare_seq(txbuff, eepcfg->size, CMD_WRITE, - (offset + eepcfg->barrier_low)); - spiSend(eepcfg->spip, txlen, txbuff); - spiSend(eepcfg->spip, len, data); - spiUnselect(eepcfg->spip); - -#if SPI_USE_MUTUAL_EXCLUSION - spiReleaseBus(eepcfg->spip); -#endif - - /* Wait until EEPROM process data. */ - now = chVTGetSystemTimeX(); - while (ll_eeprom_is_busy(eepcfg)) { - if ((chVTGetSystemTimeX() - now) > eepcfg->write_time) { - return MSG_TIMEOUT; - } - - chThdYield(); - } - - /* Lock array preventing unexpected access */ - ll_eeprom_lock(eepcfg); - return MSG_OK; -} - -/** - * @brief Determines and returns size of data that can be processed - */ -static size_t __clamp_size(void *ip, size_t n) { - - if (((size_t)eepfs_getposition(ip) + n) > (size_t)eepfs_getsize(ip)) - return eepfs_getsize(ip) - eepfs_getposition(ip); - else - return n; -} - -/** - * @brief Write data that can be fitted in one page boundary - */ -static msg_t __fitted_write(void *ip, const uint8_t *data, size_t len, uint32_t *written) { - - msg_t status = MSG_RESET; - - osalDbgAssert(len != 0, "something broken in hi level part"); - - status = ll_eeprom_write(((SPIEepromFileStream *)ip)->cfg, - eepfs_getposition(ip), data, len); - if (status == MSG_OK) { - *written += len; - eepfs_lseek(ip, eepfs_getposition(ip) + len); - } - return status; -} - -/** - * @brief Write data to EEPROM. - * @details Only one EEPROM page can be written at once. So fucntion - * splits large data chunks in small EEPROM transactions if needed. - * @note To achieve the maximum effectivity use write operations - * aligned to EEPROM page boundaries. - */ -static size_t write(void *ip, const uint8_t *bp, size_t n) { - - size_t len = 0; /* bytes to be written at one trasaction */ - uint32_t written; /* total bytes successfully written */ - uint16_t pagesize; - uint32_t firstpage; - uint32_t lastpage; - - volatile const SPIEepromFileConfig *cfg = ((SPIEepromFileStream *)ip)->cfg; - - osalDbgCheck((ip != NULL) && (((SPIEepromFileStream *)ip)->vmt != NULL)); - - if (n == 0) - return 0; - - n = __clamp_size(ip, n); - if (n == 0) - return 0; - - pagesize = cfg->pagesize; - firstpage = (cfg->barrier_low + eepfs_getposition(ip)) / pagesize; - lastpage = ((cfg->barrier_low + eepfs_getposition(ip) + n) - 1) / pagesize; - - written = 0; - /* data fitted in single page */ - if (firstpage == lastpage) { - len = n; - __fitted_write(ip, bp, len, &written); - bp += len; - return written; - } - else { - /* write first piece of data to first page boundary */ - len = ((firstpage + 1) * pagesize) - eepfs_getposition(ip); - len -= cfg->barrier_low; - __fitted_write(ip, bp, len, &written); - bp += len; - - /* now writes blocks at a size of pages (may be no one) */ - while ((n - written) > pagesize) { - len = pagesize; - if (__fitted_write(ip, bp, len, &written) != MSG_OK) // Fixed: Would increase bp forever and crash in case of timeouts... - return written; - - bp += len; - } - - - /* wrtie tail */ - len = n - written; - if (len == 0) - return written; - else { - __fitted_write(ip, bp, len, &written); - } - } - - return written; -} - -/** - * Read some bytes from current position in file. After successful - * read operation the position pointer will be increased by the number - * of read bytes. - */ -static size_t read(void *ip, uint8_t *bp, size_t n) { - - msg_t status = MSG_OK; - - osalDbgCheck((ip != NULL) && (((EepromFileStream *)ip)->vmt != NULL)); - - if (n == 0) - return 0; - - n = __clamp_size(ip, n); - if (n == 0) - return 0; - - /* call low level function */ - status = ll_eeprom_read(((SPIEepromFileStream *)ip)->cfg, - eepfs_getposition(ip), bp, n); - if (status != MSG_OK) - return 0; - else { - eepfs_lseek(ip, (eepfs_getposition(ip) + n)); - return n; - } -} - -static const struct EepromFileStreamVMT vmt = { - write, - read, - eepfs_put, - eepfs_get, - eepfs_close, - eepfs_geterror, - eepfs_getsize, - eepfs_getposition, - eepfs_lseek, -}; - -EepromDevice eepdev_25xx = { - EEPROM_DEV_25XX, - &vmt -}; - -#endif /* EEPROM_USE_EE25XX */ diff --git a/ChibiOS_16.1.5/community/os/hal/src/hal_eeprom.c b/ChibiOS_16.1.5/community/os/hal/src/hal_eeprom.c deleted file mode 100644 index f77d616..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/hal_eeprom.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - Copyright (c) 2013 Timon Wong - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -/* - Copyright 2012 Uladzimir Pylinski aka barthess. - You may use this work without restrictions, as long as this notice is included. - The work is provided "as is" without warranty of any kind, neither express nor implied. -*/ - -#include "hal_eeprom.h" -#include - -#if defined(HAL_USE_EEPROM) && HAL_USE_EEPROM - -extern EepromDevice eepdev_24xx; -extern EepromDevice eepdev_25xx; - -EepromDevice *__eeprom_drv_table[] = { - /* I2C related. */ -#if HAL_USE_I2C - -# if EEPROM_USE_EE24XX - &eepdev_24xx, -# endif - -#endif /* HAL_USE_I2C */ - - /* SPI related. */ -#if HAL_USE_SPI - -# if EEPROM_USE_EE25XX - &eepdev_25xx, -# endif - -#endif /* HAL_USE_SPI */ -}; - - -/** - * @breif Find low level EEPROM device by id. - */ -const EepromDevice *EepromFindDevice(uint8_t id) { - - uint8_t i; - const EepromDevice *drv; - - for (i = 0; i < EEPROM_TABLE_SIZE; i++) { - drv = __eeprom_drv_table[i]; - if (drv->id == id) { - return drv; - } - } - - return NULL; -} - -/** - * Open EEPROM IC as file and return pointer to the file stream object - * @note Fucntion allways successfully open file. All checking makes - * in read/write functions. - */ -EepromFileStream *EepromFileOpen(EepromFileStream *efs, - const EepromFileConfig *eepcfg, - const EepromDevice *eepdev) { - - osalDbgAssert((efs != NULL) && (eepcfg != NULL) && (eepdev != NULL) && - (eepdev->efsvmt != NULL), "EepromFileOpen"); - osalDbgAssert(efs->vmt != eepdev->efsvmt, "File allready opened"); - osalDbgAssert(eepcfg->barrier_hi > eepcfg->barrier_low, "Low barrier exceeds High barrier"); - osalDbgAssert(eepcfg->pagesize < eepcfg->size, "Pagesize cannot be lager than EEPROM size"); - osalDbgAssert(eepcfg->barrier_hi <= eepcfg->size, "Barrier exceeds EEPROM size"); - - efs->vmt = eepdev->efsvmt; - efs->cfg = eepcfg; - efs->errors = FILE_OK; - efs->position = 0; - return (EepromFileStream *)efs; -} - -uint8_t EepromReadByte(EepromFileStream *efs) { - - uint8_t buf; - fileStreamRead(efs, &buf, sizeof(buf)); - return buf; -} - -uint16_t EepromReadHalfword(EepromFileStream *efs) { - - uint16_t buf; - fileStreamRead(efs, (uint8_t *)&buf, sizeof(buf)); - return buf; -} - -uint32_t EepromReadWord(EepromFileStream *efs) { - - uint32_t buf; - fileStreamRead(efs, (uint8_t *)&buf, sizeof(buf)); - return buf; -} - -size_t EepromWriteByte(EepromFileStream *efs, uint8_t data) { - - return fileStreamWrite(efs, &data, sizeof(data)); -} - -size_t EepromWriteHalfword(EepromFileStream *efs, uint16_t data) { - - return fileStreamWrite(efs, (uint8_t *)&data, sizeof(data)); -} - -size_t EepromWriteWord(EepromFileStream *efs, uint32_t data) { - - return fileStreamWrite(efs, (uint8_t *)&data, sizeof(data)); -} - -msg_t eepfs_getsize(void *ip) { - - uint32_t h, l; - - osalDbgCheck((ip != NULL) && (((EepromFileStream *)ip)->vmt != NULL) && - (((EepromFileStream *)ip)->cfg != NULL)); - - h = ((EepromFileStream *)ip)->cfg->barrier_hi; - l = ((EepromFileStream *)ip)->cfg->barrier_low; - return h - l; -} - -msg_t eepfs_getposition(void *ip) { - - osalDbgCheck((ip != NULL) && (((EepromFileStream *)ip)->vmt != NULL)); - - return ((EepromFileStream *)ip)->position; -} - -msg_t eepfs_lseek(void *ip, fileoffset_t offset) { - - uint32_t size; - - osalDbgCheck((ip != NULL) && (((EepromFileStream *)ip)->vmt != NULL)); - - size = eepfs_getsize(ip); - if (offset > size) - offset = size; - ((EepromFileStream *)ip)->position = offset; - return offset; -} - -msg_t eepfs_close(void *ip) { - - osalDbgCheck((ip != NULL) && (((EepromFileStream *)ip)->vmt != NULL)); - - ((EepromFileStream *)ip)->errors = FILE_OK; - ((EepromFileStream *)ip)->position = 0; - ((EepromFileStream *)ip)->vmt = NULL; - ((EepromFileStream *)ip)->cfg = NULL; - return FILE_OK; -} - -msg_t eepfs_geterror(void *ip) { - - osalDbgCheck((ip != NULL) && (((EepromFileStream *)ip)->vmt != NULL)); - return ((EepromFileStream *)ip)->errors; -} - -msg_t eepfs_put(void *ip, uint8_t b) { - - (void)ip; - (void)b; - return 0; -} - -msg_t eepfs_get(void *ip) { - - (void)ip; - return 0; -} - -#endif /* #if defined(HAL_USE_EEPROM) && HAL_USE_EEPROM */ diff --git a/ChibiOS_16.1.5/community/os/hal/src/hal_eicu.c b/ChibiOS_16.1.5/community/os/hal/src/hal_eicu.c deleted file mode 100644 index f75c58b..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/hal_eicu.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ -/* - Rewritten by Emil Fresk (1/5 - 2014) for extended input capture - functionality. And fix for spurious callbacks in the interrupt handler. -*/ -/* - Improved by Uladzimir Pylinsky aka barthess (1/3 - 2015) for support of - 32-bit timers and timers with single capture/compare channels. -*/ - -/* - * Hardware Abstraction Layer for Extended Input Capture Unit - */ -#include "hal.h" - -#if (HAL_USE_EICU == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief EICU Driver initialization. - * - * @init - */ -void eicuInit(void) { - - eicu_lld_init(); -} - -/** - * @brief Initializes the standard part of a @p EICUDriver structure. - * - * @param[out] eicup Pointer to the @p EICUDriver object - * - * @init - */ -void eicuObjectInit(EICUDriver *eicup) { - - eicup->state = EICU_STOP; - eicup->config = NULL; -} - -/** - * @brief Configures and activates the EICU peripheral. - * - * @param[in] eicup Pointer to the @p EICUDriver object - * @param[in] config Pointer to the @p EICUConfig object - * - * @api - */ -void eicuStart(EICUDriver *eicup, const EICUConfig *config) { - - osalDbgCheck((eicup != NULL) && (config != NULL)); - - osalSysLock(); - osalDbgAssert((eicup->state == EICU_STOP) || (eicup->state == EICU_READY), - "invalid state"); - eicup->config = config; - eicu_lld_start(eicup); - eicup->state = EICU_READY; - osalSysUnlock(); -} - -/** - * @brief Deactivates the EICU peripheral. - * - * @param[in] eicup Pointer to the @p EICUDriver object - * - * @api - */ -void eicuStop(EICUDriver *eicup) { - - osalDbgCheck(eicup != NULL); - - osalSysLock(); - osalDbgAssert((eicup->state == EICU_STOP) || (eicup->state == EICU_READY), - "invalid state"); - eicu_lld_stop(eicup); - eicup->state = EICU_STOP; - osalSysUnlock(); -} - -/** - * @brief Enables the extended input capture. - * - * @param[in] eicup Pointer to the @p EICUDriver object - * - * @api - */ -void eicuEnable(EICUDriver *eicup) { - - osalDbgCheck(eicup != NULL); - - osalSysLock(); - osalDbgAssert(eicup->state == EICU_READY, "invalid state"); - eicu_lld_enable(eicup); - eicup->state = EICU_WAITING; - osalSysUnlock(); -} - -/** - * @brief Disables the extended input capture. - * - * @param[in] eicup Pointer to the @p EICUDriver object - * - * @api - */ -void eicuDisable(EICUDriver *eicup) { - - osalDbgCheck(eicup != NULL); - - osalSysLock(); - osalDbgAssert((eicup->state == EICU_READY) || (eicup->state == EICU_IDLE) || - (eicup->state == EICU_ACTIVE) || (eicup->state == EICU_WAITING), - "invalid state"); - eicu_lld_disable(eicup); - eicup->state = EICU_READY; - osalSysUnlock(); -} - -#endif /* HAL_USE_EICU */ diff --git a/ChibiOS_16.1.5/community/os/hal/src/hal_nand.c b/ChibiOS_16.1.5/community/os/hal/src/hal_nand.c deleted file mode 100644 index 24dd6de..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/hal_nand.c +++ /dev/null @@ -1,567 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2014 Uladzimir Pylinsky aka barthess - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/** - * @file nand.c - * @brief NAND Driver code. - * - * @addtogroup NAND - * @{ - */ - -#include "hal.h" - -#if (HAL_USE_NAND == TRUE) || defined(__DOXYGEN__) - -#include "string.h" /* for memset */ - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Check page size. - * - * @param[in] page_data_size size of page data area - * - * @notapi - */ -static void pagesize_check(size_t page_data_size) { - - /* Page size out of bounds.*/ - osalDbgCheck((page_data_size >= NAND_MIN_PAGE_SIZE) && - (page_data_size <= NAND_MAX_PAGE_SIZE)); - - /* Page size must be power of 2.*/ - osalDbgCheck(((page_data_size - 1) & page_data_size) == 0); -} - -/** - * @brief Translate block-page-offset scheme to NAND internal address. - * - * @param[in] cfg pointer to the @p NANDConfig from - * corresponding NAND driver - * @param[in] block block number - * @param[in] page page number related to begin of block - * @param[in] page_offset data offset related to begin of page - * @param[out] addr buffer to store calculated address - * @param[in] addr_len length of address buffer - * - * @notapi - */ -static void calc_addr(const NANDConfig *cfg, uint32_t block, uint32_t page, - uint32_t page_offset, uint8_t *addr, size_t addr_len) { - size_t i = 0; - uint32_t row = 0; - - /* Incorrect buffer length.*/ - osalDbgCheck(cfg->rowcycles + cfg->colcycles == addr_len); - osalDbgCheck((block < cfg->blocks) && (page < cfg->pages_per_block) && - (page_offset < cfg->page_data_size + cfg->page_spare_size)); - - /* convert address to NAND specific */ - memset(addr, 0, addr_len); - row = (block * cfg->pages_per_block) + page; - for (i=0; icolcycles; i++){ - addr[i] = page_offset & 0xFF; - page_offset = page_offset >> 8; - } - for (; i> 8; - } -} - -/** - * @brief Translate block number to NAND internal address. - * @note This function designed for erasing purpose. - * - * @param[in] cfg pointer to the @p NANDConfig from - * corresponding NAND driver - * @param[in] block block number - * @param[out] addr buffer to store calculated address - * @param[in] addr_len length of address buffer - * - * @notapi - */ -static void calc_blk_addr(const NANDConfig *cfg, uint32_t block, - uint8_t *addr, size_t addr_len) { - size_t i = 0; - uint32_t row = 0; - - /* Incorrect buffer length.*/ - osalDbgCheck(cfg->rowcycles == addr_len); - osalDbgCheck((block < cfg->blocks)); - - /* convert address to NAND specific */ - memset(addr, 0, addr_len); - row = block * cfg->pages_per_block; - for (i=0; i> 8; - } -} - -/** - * @brief Read block badness mark directly from NAND memory array. - * - * @param[in] nandp pointer to the @p NANDDriver object - * @param[in] block block number - * - * @return block condition - * @retval true if the block is bad. - * @retval false if the block is good. - * - * @notapi - */ -static bool read_is_block_bad(NANDDriver *nandp, size_t block) { - - if (0xFF != nandReadBadMark(nandp, block, 0)) - return true; - if (0xFF != nandReadBadMark(nandp, block, 1)) - return true; - - return false; -} - -/** - * @brief Scan for bad blocks and fill map with their numbers. - * - * @param[in] nandp pointer to the @p NANDDriver object - * - * @notapi - */ -static void scan_bad_blocks(NANDDriver *nandp) { - - const size_t blocks = nandp->config->blocks; - size_t b; - - osalDbgCheck(bitmapGetBitsCount(nandp->bb_map) >= blocks); - - /* clear map just to be safe */ - bitmapObjectInit(nandp->bb_map, 0); - - /* now write numbers of bad block to map */ - for (b=0; bbb_map, b); - } - } -} - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief NAND Driver initialization. - * @note This function is implicitly invoked by @p halInit(), there is - * no need to explicitly initialize the driver. - * - * @init - */ -void nandInit(void) { - - nand_lld_init(); -} - -/** - * @brief Initializes the standard part of a @p NANDDriver structure. - * - * @param[out] nandp pointer to the @p NANDDriver object - * - * @init - */ -void nandObjectInit(NANDDriver *nandp) { - -#if NAND_USE_MUTUAL_EXCLUSION -#if CH_CFG_USE_MUTEXES - chMtxObjectInit(&nandp->mutex); -#else - chSemObjectInit(&nandp->semaphore, 1); -#endif /* CH_CFG_USE_MUTEXES */ -#endif /* NAND_USE_MUTUAL_EXCLUSION */ - - nandp->state = NAND_STOP; - nandp->config = NULL; -} - -/** - * @brief Configures and activates the NAND peripheral. - * - * @param[in] nandp pointer to the @p NANDDriver object - * @param[in] config pointer to the @p NANDConfig object - * @param[in] bb_map pointer to the bad block map or @NULL if not need - * - * @api - */ -void nandStart(NANDDriver *nandp, const NANDConfig *config, bitmap_t *bb_map) { - - osalDbgCheck((nandp != NULL) && (config != NULL)); - osalDbgAssert((nandp->state == NAND_STOP) || - (nandp->state == NAND_READY), - "invalid state"); - - nandp->config = config; - pagesize_check(nandp->config->page_data_size); - nand_lld_start(nandp); - nandp->state = NAND_READY; - - if (NULL != bb_map) { - nandp->bb_map = bb_map; - scan_bad_blocks(nandp); - } -} - -/** - * @brief Deactivates the NAND peripheral. - * - * @param[in] nandp pointer to the @p NANDDriver object - * - * @api - */ -void nandStop(NANDDriver *nandp) { - - osalDbgCheck(nandp != NULL); - osalDbgAssert((nandp->state == NAND_STOP) || - (nandp->state == NAND_READY), - "invalid state"); - nand_lld_stop(nandp); - nandp->state = NAND_STOP; -} - -/** - * @brief Read whole page. - * - * @param[in] nandp pointer to the @p NANDDriver object - * @param[in] block block number - * @param[in] page page number related to begin of block - * @param[out] data buffer to store data - * @param[in] datalen length of data buffer - * - * @api - */ -void nandReadPageWhole(NANDDriver *nandp, uint32_t block, uint32_t page, - uint8_t *data, size_t datalen) { - - const NANDConfig *cfg = nandp->config; - uint8_t addrbuf[8]; - size_t addrlen = cfg->rowcycles + cfg->colcycles; - - osalDbgCheck((nandp != NULL) && (data != NULL)); - osalDbgCheck((datalen <= (cfg->page_data_size + cfg->page_spare_size))); - osalDbgAssert(nandp->state == NAND_READY, "invalid state"); - - calc_addr(cfg, block, page, 0, addrbuf, addrlen); - nand_lld_read_data(nandp, data, datalen, addrbuf, addrlen, NULL); -} - -/** - * @brief Write whole page. - * - * @param[in] nandp pointer to the @p NANDDriver object - * @param[in] block block number - * @param[in] page page number related to begin of block - * @param[in] data buffer with data to be written - * @param[in] datalen length of data buffer - * - * @return The operation status reported by NAND IC (0x70 command). - * - * @api - */ -uint8_t nandWritePageWhole(NANDDriver *nandp, uint32_t block, uint32_t page, - const uint8_t *data, size_t datalen) { - - uint8_t retval; - const NANDConfig *cfg = nandp->config; - uint8_t addr[8]; - size_t addrlen = cfg->rowcycles + cfg->colcycles; - - osalDbgCheck((nandp != NULL) && (data != NULL)); - osalDbgCheck((datalen <= (cfg->page_data_size + cfg->page_spare_size))); - osalDbgAssert(nandp->state == NAND_READY, "invalid state"); - - calc_addr(cfg, block, page, 0, addr, addrlen); - retval = nand_lld_write_data(nandp, data, datalen, addr, addrlen, NULL); - return retval; -} - -/** - * @brief Read page data without spare area. - * - * @param[in] nandp pointer to the @p NANDDriver object - * @param[in] block block number - * @param[in] page page number related to begin of block - * @param[out] data buffer to store data - * @param[in] datalen length of data buffer - * @param[out] ecc pointer to calculated ECC. Ignored when NULL. - * - * @api - */ -void nandReadPageData(NANDDriver *nandp, uint32_t block, uint32_t page, - uint8_t *data, size_t datalen, uint32_t *ecc) { - - const NANDConfig *cfg = nandp->config; - uint8_t addrbuf[8]; - size_t addrlen = cfg->rowcycles + cfg->colcycles; - - osalDbgCheck((nandp != NULL) && (data != NULL)); - osalDbgCheck((datalen <= cfg->page_data_size)); - osalDbgAssert(nandp->state == NAND_READY, "invalid state"); - - calc_addr(cfg, block, page, 0, addrbuf, addrlen); - nand_lld_read_data(nandp, data, datalen, addrbuf, addrlen, ecc); -} - -/** - * @brief Write page data without spare area. - * - * @param[in] nandp pointer to the @p NANDDriver object - * @param[in] block block number - * @param[in] page page number related to begin of block - * @param[in] data buffer with data to be written - * @param[in] datalen length of data buffer - * @param[out] ecc pointer to calculated ECC. Ignored when NULL. - * - * @return The operation status reported by NAND IC (0x70 command). - * - * @api - */ -uint8_t nandWritePageData(NANDDriver *nandp, uint32_t block, uint32_t page, - const uint8_t *data, size_t datalen, uint32_t *ecc) { - - uint8_t retval; - const NANDConfig *cfg = nandp->config; - uint8_t addr[8]; - size_t addrlen = cfg->rowcycles + cfg->colcycles; - - osalDbgCheck((nandp != NULL) && (data != NULL)); - osalDbgCheck((datalen <= cfg->page_data_size)); - osalDbgAssert(nandp->state == NAND_READY, "invalid state"); - - calc_addr(cfg, block, page, 0, addr, addrlen); - retval = nand_lld_write_data(nandp, data, datalen, addr, addrlen, ecc); - return retval; -} - -/** - * @brief Read page spare area. - * - * @param[in] nandp pointer to the @p NANDDriver object - * @param[in] block block number - * @param[in] page page number related to begin of block - * @param[out] spare buffer to store data - * @param[in] sparelen length of data buffer - * - * @api - */ -void nandReadPageSpare(NANDDriver *nandp, uint32_t block, uint32_t page, - uint8_t *spare, size_t sparelen) { - - const NANDConfig *cfg = nandp->config; - uint8_t addr[8]; - size_t addrlen = cfg->rowcycles + cfg->colcycles; - - osalDbgCheck((NULL != spare) && (nandp != NULL)); - osalDbgCheck(sparelen <= cfg->page_spare_size); - osalDbgAssert(nandp->state == NAND_READY, "invalid state"); - - calc_addr(cfg, block, page, cfg->page_data_size, addr, addrlen); - nand_lld_read_data(nandp, spare, sparelen, addr, addrlen, NULL); -} - -/** - * @brief Write page spare area. - * - * @param[in] nandp pointer to the @p NANDDriver object - * @param[in] block block number - * @param[in] page page number related to begin of block - * @param[in] spare buffer with spare data to be written - * @param[in] sparelen length of data buffer - * - * @return The operation status reported by NAND IC (0x70 command). - * - * @api - */ -uint8_t nandWritePageSpare(NANDDriver *nandp, uint32_t block, uint32_t page, - const uint8_t *spare, size_t sparelen) { - - uint8_t retVal; - const NANDConfig *cfg = nandp->config; - uint8_t addr[8]; - size_t addrlen = cfg->rowcycles + cfg->colcycles; - - osalDbgCheck((NULL != spare) && (nandp != NULL)); - osalDbgCheck(sparelen <= cfg->page_spare_size); - osalDbgAssert(nandp->state == NAND_READY, "invalid state"); - - calc_addr(cfg, block, page, cfg->page_data_size, addr, addrlen); - retVal = nand_lld_write_data(nandp, spare, sparelen, addr, addrlen, NULL); - return retVal; -} - -/** - * @brief Mark block as bad. - * - * @param[in] nandp pointer to the @p NANDDriver object - * @param[in] block block number - * - * @api - */ -void nandMarkBad(NANDDriver *nandp, uint32_t block) { - - uint8_t bb_mark[2] = {0, 0}; - - nandWritePageSpare(nandp, block, 0, bb_mark, sizeof(bb_mark)); - nandWritePageSpare(nandp, block, 1, bb_mark, sizeof(bb_mark)); - - if (NULL != nandp->bb_map) - bitmapSet(nandp->bb_map, block); -} - -/** - * @brief Read bad mark out. - * - * @param[in] nandp pointer to the @p NANDDriver object - * @param[in] block block number - * @param[in] page page number related to begin of block - * - * @return Bad mark. - * - * @api - */ -uint8_t nandReadBadMark(NANDDriver *nandp, uint32_t block, uint32_t page) { - uint8_t bb_mark[1]; - - nandReadPageSpare(nandp, block, page, bb_mark, sizeof(bb_mark)); - return bb_mark[0]; -} - -/** - * @brief Erase block. - * - * @param[in] nandp pointer to the @p NANDDriver object - * @param[in] block block number - * - * @return The operation status reported by NAND IC (0x70 command). - * - * @api - */ -uint8_t nandErase(NANDDriver *nandp, uint32_t block) { - - uint8_t retVal; - const NANDConfig *cfg = nandp->config; - uint8_t addr[4]; - size_t addrlen = cfg->rowcycles; - - osalDbgCheck(nandp != NULL); - osalDbgAssert(nandp->state == NAND_READY, "invalid state"); - - calc_blk_addr(cfg, block, addr, addrlen); - retVal = nand_lld_erase(nandp, addr, addrlen); - return retVal; -} - -/** - * @brief Check block badness. - * - * @param[in] nandp pointer to the @p NANDDriver object - * @param[in] block block number - * - * @return block condition - * @retval true if the block is bad. - * @retval false if the block is good. - * - * @api - */ -bool nandIsBad(NANDDriver *nandp, uint32_t block) { - - osalDbgCheck(nandp != NULL); - osalDbgAssert(nandp->state == NAND_READY, "invalid state"); - - if (NULL != nandp->bb_map) - return 1 == bitmapGet(nandp->bb_map, block); - else - return read_is_block_bad(nandp, block); -} - -#if NAND_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) -/** - * @brief Gains exclusive access to the NAND bus. - * @details This function tries to gain ownership to the NAND bus, if the bus - * is already being used then the invoking thread is queued. - * @pre In order to use this function the option - * @p NAND_USE_MUTUAL_EXCLUSION must be enabled. - * - * @param[in] nandp pointer to the @p NANDDriver object - * - * @api - */ -void nandAcquireBus(NANDDriver *nandp) { - - osalDbgCheck(nandp != NULL); - -#if CH_CFG_USE_MUTEXES - chMtxLock(&nandp->mutex); -#elif CH_CFG_USE_SEMAPHORES - chSemWait(&nandp->semaphore); -#endif -} - -/** - * @brief Releases exclusive access to the NAND bus. - * @pre In order to use this function the option - * @p NAND_USE_MUTUAL_EXCLUSION must be enabled. - * - * @param[in] nandp pointer to the @p NANDDriver object - * - * @api - */ -void nandReleaseBus(NANDDriver *nandp) { - - osalDbgCheck(nandp != NULL); - -#if CH_CFG_USE_MUTEXES - chMtxUnlock(&nandp->mutex); -#elif CH_CFG_USE_SEMAPHORES - chSemSignal(&nandp->semaphore); -#endif -} -#endif /* NAND_USE_MUTUAL_EXCLUSION */ - -#endif /* HAL_USE_NAND */ - -/** @} */ - - - - diff --git a/ChibiOS_16.1.5/community/os/hal/src/hal_onewire.c b/ChibiOS_16.1.5/community/os/hal/src/hal_onewire.c deleted file mode 100644 index a93eec0..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/hal_onewire.c +++ /dev/null @@ -1,890 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2014 Uladzimir Pylinsky aka barthess - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/*===========================================================================*/ -/* Main ideas: */ -/*=========================================================================== - -1) switch PWM output pin to open drain mode. -2) start 2 channels _simultaneously_. First (master channel) generates - pulses (read time slots) second (sample channel) generates interrupts - from where read pin function will be called. - -- --------------------------------------- master channel generates pulses - | / . - --............................. <---------- slave (not)pulls down bus here -- -------------------------------- sample channel reads pad state - | | - ------------- - ^ - | read interrupt fires here - -For data write it is only master channel needed. Data bit width updates -on every timer overflow event. -*/ - -/*===========================================================================*/ -/* General recommendations for strong pull usage */ -/*=========================================================================== - * 1) Use separate power rail instead of strong pull up whenever possible. - * Driver's strong pull up feature is very sensible to interrupt jitter. - * 2) Use specialized 1-wire bus master (DS2484 for example) if you are - * forced to handle bus requiring strong pull up feature. - */ - -/** - * @file onewire.c - * @brief 1-wire Driver code. - * - * @addtogroup onewire - * @{ - */ - -#include "hal.h" - -#if (HAL_USE_ONEWIRE == TRUE) || defined(__DOXYGEN__) - -#include -#include - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ -/** - * @brief 1MHz clock for PWM driver. - */ -#define ONEWIRE_PWM_FREQUENCY 1000000 - -/** - * @brief Pulse width constants in microseconds. - * @details Inspired by Microchip's AN1199 - * "1-Wire® Communication with PIC® Microcontroller" - */ -#define ONEWIRE_ZERO_WIDTH 60 -#define ONEWIRE_ONE_WIDTH 6 -#define ONEWIRE_SAMPLE_WIDTH 15 -#define ONEWIRE_RECOVERY_WIDTH 10 -#define ONEWIRE_RESET_LOW_WIDTH 480 -#define ONEWIRE_RESET_SAMPLE_WIDTH 550 -#define ONEWIRE_RESET_TOTAL_WIDTH 960 - -/** - * @brief Local function declarations. - */ -static void ow_reset_cb(PWMDriver *pwmp, onewireDriver *owp); -static void pwm_reset_cb(PWMDriver *pwmp); -static void ow_read_bit_cb(PWMDriver *pwmp, onewireDriver *owp); -static void pwm_read_bit_cb(PWMDriver *pwmp); -static void ow_write_bit_cb(PWMDriver *pwmp, onewireDriver *owp); -static void pwm_write_bit_cb(PWMDriver *pwmp); -#if ONEWIRE_USE_SEARCH_ROM -static void ow_search_rom_cb(PWMDriver *pwmp, onewireDriver *owp); -static void pwm_search_rom_cb(PWMDriver *pwmp); -#endif - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ -/** - * @brief 1-wire driver identifier. - */ -onewireDriver OWD1; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ -/** - * @brief Look up table for fast 1-wire CRC calculation - */ -static const uint8_t onewire_crc_table[256] = { - 0x0, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83, - 0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41, - 0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e, - 0x5f, 0x1, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc, - 0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0, - 0xe1, 0xbf, 0x5d, 0x3, 0x80, 0xde, 0x3c, 0x62, - 0xbe, 0xe0, 0x2, 0x5c, 0xdf, 0x81, 0x63, 0x3d, - 0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff, - 0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5, - 0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x7, - 0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x6, 0x58, - 0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a, - 0x65, 0x3b, 0xd9, 0x87, 0x4, 0x5a, 0xb8, 0xe6, - 0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24, - 0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b, - 0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x5, 0xe7, 0xb9, - 0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0xf, - 0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd, - 0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92, - 0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0xe, 0x50, - 0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c, - 0x6d, 0x33, 0xd1, 0x8f, 0xc, 0x52, 0xb0, 0xee, - 0x32, 0x6c, 0x8e, 0xd0, 0x53, 0xd, 0xef, 0xb1, - 0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73, - 0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49, - 0x8, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b, - 0x57, 0x9, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4, - 0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16, - 0xe9, 0xb7, 0x55, 0xb, 0x88, 0xd6, 0x34, 0x6a, - 0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8, - 0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7, - 0xb6, 0xe8, 0xa, 0x54, 0xd7, 0x89, 0x6b, 0x35 -}; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ -/** - * @brief Put bus in idle mode. - */ -static void ow_bus_idle(onewireDriver *owp) { -#if defined(STM32F1XX) - palSetPadMode(owp->config->port, owp->config->pad, - owp->config->pad_mode_idle); -#endif - pwmStop(owp->config->pwmd); -} - -/** - * @brief Put bus in active mode. - */ -static void ow_bus_active(onewireDriver *owp) { - pwmStart(owp->config->pwmd, owp->config->pwmcfg); -#if defined(STM32F1XX) - palSetPadMode(owp->config->port, owp->config->pad, - owp->config->pad_mode_active); -#endif -} - -/** - * @brief Function performing read of single bit. - * @note It must be callable from any context. - */ -static ioline_t ow_read_bit(onewireDriver *owp) { -#if ONEWIRE_SYNTH_SEARCH_TEST - (void)owp; - return _synth_ow_read_bit(); -#else - return palReadPad(owp->config->port, owp->config->pad); -#endif -} - -/** - * @brief PWM adapter - */ -static void pwm_reset_cb(PWMDriver *pwmp) { - ow_reset_cb(pwmp, &OWD1); -} - -/** - * @brief PWM adapter - */ -static void pwm_read_bit_cb(PWMDriver *pwmp) { - ow_read_bit_cb(pwmp, &OWD1); -} - -/** - * @brief PWM adapter - */ -static void pwm_write_bit_cb(PWMDriver *pwmp) { - ow_write_bit_cb(pwmp, &OWD1); -} - -#if ONEWIRE_USE_SEARCH_ROM -/** - * @brief PWM adapter - */ -static void pwm_search_rom_cb(PWMDriver *pwmp) { - ow_search_rom_cb(pwmp, &OWD1); -} -#endif /* ONEWIRE_USE_SEARCH_ROM */ - -/** - * @brief Write bit routine. - * @details Switch PWM channel to 'width' or 'narrow' pulse depending - * on value of bit need to be transmitted. - * - * @param[in] owp pointer to the @p onewireDriver object - * @param[in] bit value to be written - * - * @notapi - */ -static void ow_write_bit_I(onewireDriver *owp, ioline_t bit) { -#if ONEWIRE_SYNTH_SEARCH_TEST - _synth_ow_write_bit(owp, bit); -#else - osalSysLockFromISR(); - if (0 == bit) { - pwmEnableChannelI(owp->config->pwmd, owp->config->master_channel, - ONEWIRE_ZERO_WIDTH); - } - else { - pwmEnableChannelI(owp->config->pwmd, owp->config->master_channel, - ONEWIRE_ONE_WIDTH); - } - osalSysUnlockFromISR(); -#endif -} - -/** - * @brief 1-wire reset pulse callback. - * @note Must be called from PWM's ISR. - * - * @param[in] pwmp pointer to the @p PWMDriver object - * @param[in] owp pointer to the @p onewireDriver object - * - * @notapi - */ -static void ow_reset_cb(PWMDriver *pwmp, onewireDriver *owp) { - - owp->reg.slave_present = (PAL_LOW == ow_read_bit(owp)); - - osalSysLockFromISR(); - pwmDisableChannelI(pwmp, owp->config->sample_channel); - osalThreadResumeI(&owp->thread, MSG_OK); - osalSysUnlockFromISR(); -} - -/** - * @brief 1-wire read bit callback. - * @note Must be called from PWM's ISR. - * - * @param[in] pwmp pointer to the @p PWMDriver object - * @param[in] owp pointer to the @p onewireDriver object - * - * @notapi - */ -static void ow_read_bit_cb(PWMDriver *pwmp, onewireDriver *owp) { - - if (true == owp->reg.final_timeslot) { - osalSysLockFromISR(); - pwmDisableChannelI(pwmp, owp->config->sample_channel); - osalThreadResumeI(&owp->thread, MSG_OK); - osalSysUnlockFromISR(); - return; - } - else { - *owp->buf |= ow_read_bit(owp) << owp->reg.bit; - owp->reg.bit++; - if (8 == owp->reg.bit) { - owp->reg.bit = 0; - owp->buf++; - owp->reg.bytes--; - if (0 == owp->reg.bytes) { - owp->reg.final_timeslot = true; - osalSysLockFromISR(); - /* Only master channel must be stopped here. - Sample channel will be stopped in next ISR call. - It is still needed to generate final interrupt. */ - pwmDisableChannelI(pwmp, owp->config->master_channel); - osalSysUnlockFromISR(); - } - } - } -} - -/** - * @brief 1-wire bit transmission callback. - * @note Must be called from PWM's ISR. - * - * @param[in] pwmp pointer to the @p PWMDriver object - * @param[in] owp pointer to the @p onewireDriver object - * - * @notapi - */ -static void ow_write_bit_cb(PWMDriver *pwmp, onewireDriver *owp) { - - if (8 == owp->reg.bit) { - owp->buf++; - owp->reg.bit = 0; - owp->reg.bytes--; - - if (0 == owp->reg.bytes) { - osalSysLockFromISR(); - pwmDisableChannelI(pwmp, owp->config->master_channel); - osalSysUnlockFromISR(); - /* used to prevent premature timer stop from userspace */ - owp->reg.final_timeslot = true; - return; - } - } - - /* wait until timer generate last pulse */ - if (true == owp->reg.final_timeslot) { - #if ONEWIRE_USE_STRONG_PULLUP - if (owp->reg.need_pullup) { - owp->reg.state = ONEWIRE_PULL_UP; - owp->config->pullup_assert(); - owp->reg.need_pullup = false; - } - #endif - - osalSysLockFromISR(); - osalThreadResumeI(&owp->thread, MSG_OK); - osalSysUnlockFromISR(); - return; - } - - ow_write_bit_I(owp, (*owp->buf >> owp->reg.bit) & 1); - owp->reg.bit++; -} - -#if ONEWIRE_USE_SEARCH_ROM -/** - * @brief Helper function for collision handler - * - * @param[in] sr pointer to the @p onewire_search_rom_t helper structure - * @param[in] bit discovered bit to be stored in helper structure - */ -static void store_bit(onewire_search_rom_t *sr, uint8_t bit) { - - size_t rb = sr->reg.rombit; - - sr->retbuf[rb / CHAR_BIT] |= bit << (rb % CHAR_BIT); - sr->reg.rombit++; -} - -/** - * @brief Helper function for collision handler - * @details Extract bit from previous search path. - * - * @param[in] path pointer to the array with previous path stored in - * 'search ROM' helper structure - * @param[in] bit number of bit [0..63] - */ -static uint8_t extract_path_bit(const uint8_t *path, size_t bit) { - - return (path[bit / CHAR_BIT] >> (bit % CHAR_BIT)) & 1; -} - -/** - * @brief Collision handler for 'search ROM' procedure. - * @details You can find algorithm details in APPNOTE 187 - * "1-Wire Search Algorithm" from Maxim - * - * @param[in,out] sr pointer to the @p onewire_search_rom_t helper structure - */ -static uint8_t collision_handler(onewire_search_rom_t *sr) { - - uint8_t bit; - - switch(sr->reg.search_iter) { - case ONEWIRE_SEARCH_ROM_NEXT: - if ((int)sr->reg.rombit < sr->last_zero_branch) { - bit = extract_path_bit(sr->prev_path, sr->reg.rombit); - if (0 == bit) { - sr->prev_zero_branch = sr->reg.rombit; - sr->reg.result = ONEWIRE_SEARCH_ROM_SUCCESS; - } - store_bit(sr, bit); - return bit; - } - else if ((int)sr->reg.rombit == sr->last_zero_branch) { - sr->last_zero_branch = sr->prev_zero_branch; - store_bit(sr, 1); - return 1; - } - else { - /* found next branch some levels deeper */ - sr->prev_zero_branch = sr->last_zero_branch; - sr->last_zero_branch = sr->reg.rombit; - store_bit(sr, 0); - sr->reg.result = ONEWIRE_SEARCH_ROM_SUCCESS; - return 0; - } - break; - - case ONEWIRE_SEARCH_ROM_FIRST: - /* always take 0-branch */ - sr->prev_zero_branch = sr->last_zero_branch; - sr->last_zero_branch = sr->reg.rombit; - store_bit(sr, 0); - sr->reg.result = ONEWIRE_SEARCH_ROM_SUCCESS; - return 0; - break; - - default: - osalSysHalt("Unhandled case"); - return 0; /* warning supressor */ - break; - } -} - -/** - * @brief 1-wire search ROM callback. - * @note Must be called from PWM's ISR. - * - * @param[in] pwmp pointer to the @p PWMDriver object - * @param[in] owp pointer to the @p onewireDriver object - * - * @notapi - */ -static void ow_search_rom_cb(PWMDriver *pwmp, onewireDriver *owp) { - - onewire_search_rom_t *sr = &owp->search_rom; - - if (0 == sr->reg.bit_step) { /* read direct bit */ - sr->reg.bit_buf |= ow_read_bit(owp); - sr->reg.bit_step++; - } - else if (1 == sr->reg.bit_step) { /* read complement bit */ - sr->reg.bit_buf |= ow_read_bit(owp) << 1; - sr->reg.bit_step++; - switch(sr->reg.bit_buf){ - case 0b11: - /* no one device on bus or any other fail happened */ - sr->reg.result = ONEWIRE_SEARCH_ROM_ERROR; - goto THE_END; - break; - case 0b01: - /* all slaves have 1 in this position */ - store_bit(sr, 1); - ow_write_bit_I(owp, 1); - break; - case 0b10: - /* all slaves have 0 in this position */ - store_bit(sr, 0); - ow_write_bit_I(owp, 0); - break; - case 0b00: - /* collision */ - sr->reg.single_device = false; - ow_write_bit_I(owp, collision_handler(sr)); - break; - } - } - else { /* start next step */ - #if !ONEWIRE_SYNTH_SEARCH_TEST - ow_write_bit_I(owp, 1); - #endif - sr->reg.bit_step = 0; - sr->reg.bit_buf = 0; - } - - /* one ROM successfully discovered */ - if (64 == sr->reg.rombit) { - sr->reg.devices_found++; - sr->reg.search_iter = ONEWIRE_SEARCH_ROM_NEXT; - if (true == sr->reg.single_device) - sr->reg.result = ONEWIRE_SEARCH_ROM_LAST; - goto THE_END; - } - return; /* next search bit iteration */ - -THE_END: -#if ONEWIRE_SYNTH_SEARCH_TEST - (void)pwmp; - return; -#else - osalSysLockFromISR(); - pwmDisableChannelI(pwmp, owp->config->master_channel); - pwmDisableChannelI(pwmp, owp->config->sample_channel); - osalThreadResumeI(&(owp)->thread, MSG_OK); - osalSysUnlockFromISR(); -#endif -} - -/** - * @brief Helper function. Initialize structures required by 'search ROM'. - * @details Early reset. Call it once before 'search ROM' routine. - * - * @param[in] sr pointer to the @p onewire_search_rom_t helper structure - */ -static void search_clean_start(onewire_search_rom_t *sr) { - - sr->reg.single_device = true; /* presume simplest way at beginning */ - sr->reg.result = ONEWIRE_SEARCH_ROM_LAST; - sr->reg.search_iter = ONEWIRE_SEARCH_ROM_FIRST; - sr->retbuf = NULL; - sr->reg.devices_found = 0; - memset(sr->prev_path, 0, 8); - - sr->reg.rombit = 0; - sr->reg.bit_step = 0; - sr->reg.bit_buf = 0; - sr->last_zero_branch = -1; - sr->prev_zero_branch = -1; -} - -/** - * @brief Helper function. Prepare structures required by 'search ROM'. - * - * @param[in] sr pointer to the @p onewire_search_rom_t helper structure - */ -static void search_clean_iteration(onewire_search_rom_t *sr) { - - sr->reg.rombit = 0; - sr->reg.bit_step = 0; - sr->reg.bit_buf = 0; - sr->reg.result = ONEWIRE_SEARCH_ROM_LAST; -} -#endif /* ONEWIRE_USE_SEARCH_ROM */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Calculates 1-wire CRC. - * - * @param[in] buf pointer to the data buffer - * @param[in] len lenght of data buffer - * - * @init - */ -uint8_t onewireCRC(const uint8_t *buf, size_t len) { - uint8_t ret = 0; - size_t i; - - for (i=0; iconfig = NULL; - owp->reg.slave_present = false; - owp->reg.state = ONEWIRE_STOP; - owp->thread = NULL; - - owp->reg.bytes = 0; - owp->reg.bit = 0; - owp->reg.final_timeslot = false; - owp->buf = NULL; - -#if ONEWIRE_USE_STRONG_PULLUP - owp->reg.need_pullup = false; -#endif -} - -/** - * @brief Configures and activates the 1-wire driver. - * - * @param[in] owp pointer to the @p onewireDriver object - * @param[in] config pointer to the @p onewireConfig object - * - * @api - */ -void onewireStart(onewireDriver *owp, const onewireConfig *config) { - - osalDbgCheck((NULL != owp) && (NULL != config)); - osalDbgAssert(PWM_STOP == config->pwmd->state, - "PWM will be started by onewire driver internally"); - osalDbgAssert(ONEWIRE_STOP == owp->reg.state, "Invalid state"); -#if ONEWIRE_USE_STRONG_PULLUP - osalDbgCheck((NULL != config->pullup_assert) && - (NULL != config->pullup_release)); -#endif - - owp->config = config; - owp->config->pwmcfg->frequency = ONEWIRE_PWM_FREQUENCY; - owp->config->pwmcfg->period = ONEWIRE_RESET_TOTAL_WIDTH; - -#if !defined(STM32F1XX) - palSetPadMode(owp->config->port, owp->config->pad, - owp->config->pad_mode_active); -#endif - ow_bus_idle(owp); - owp->reg.state = ONEWIRE_READY; -} - -/** - * @brief Deactivates the UART peripheral. - * - * @param[in] owp pointer to the @p onewireDriver object - * - * @api - */ -void onewireStop(onewireDriver *owp) { - osalDbgCheck(NULL != owp); -#if ONEWIRE_USE_STRONG_PULLUP - owp->config->pullup_release(); -#endif - ow_bus_idle(owp); - pwmStop(owp->config->pwmd); - owp->config = NULL; - owp->reg.state = ONEWIRE_STOP; -} - -/** - * @brief Generate reset pulse on bus. - * - * @param[in] owp pointer to the @p onewireDriver object - * - * @return Bool flag denoting device presence. - * @retval true There is at least one device on bus. - */ -bool onewireReset(onewireDriver *owp) { - PWMDriver *pwmd; - PWMConfig *pwmcfg; - size_t mch, sch; - - osalDbgCheck(NULL != owp); - osalDbgAssert(owp->reg.state == ONEWIRE_READY, "Invalid state"); - - /* short circuit on bus or any other device transmit data */ - if (PAL_LOW == ow_read_bit(owp)) - return false; - - pwmd = owp->config->pwmd; - pwmcfg = owp->config->pwmcfg; - mch = owp->config->master_channel; - sch = owp->config->sample_channel; - - - pwmcfg->period = ONEWIRE_RESET_LOW_WIDTH + ONEWIRE_RESET_SAMPLE_WIDTH; - pwmcfg->callback = NULL; - pwmcfg->channels[mch].callback = NULL; - pwmcfg->channels[mch].mode = owp->config->pwmmode; - pwmcfg->channels[sch].callback = pwm_reset_cb; - pwmcfg->channels[sch].mode = PWM_OUTPUT_ACTIVE_LOW; - - ow_bus_active(owp); - - osalSysLock(); - pwmEnableChannelI(pwmd, mch, ONEWIRE_RESET_LOW_WIDTH); - pwmEnableChannelI(pwmd, sch, ONEWIRE_RESET_SAMPLE_WIDTH); - pwmEnableChannelNotificationI(pwmd, sch); - osalThreadSuspendS(&owp->thread); - osalSysUnlock(); - - ow_bus_idle(owp); - - /* wait until slave release bus to discriminate short circuit condition */ - osalThreadSleepMicroseconds(500); - return (PAL_HIGH == ow_read_bit(owp)) && (true == owp->reg.slave_present); -} - -/** - * @brief Read some bites from slave device. - * - * @param[in] owp pointer to the @p onewireDriver object - * @param[out] rxbuf pointer to the buffer for read data - * @param[in] rxbytes amount of data to be received - */ -void onewireRead(onewireDriver *owp, uint8_t *rxbuf, size_t rxbytes) { - PWMDriver *pwmd; - PWMConfig *pwmcfg; - size_t mch, sch; - - osalDbgCheck((NULL != owp) && (NULL != rxbuf)); - osalDbgCheck((rxbytes > 0) && (rxbytes <= ONEWIRE_MAX_TRANSACTION_LEN)); - osalDbgAssert(owp->reg.state == ONEWIRE_READY, "Invalid state"); - - /* Buffer zeroing. This is important because of driver collects - bits using |= operation.*/ - memset(rxbuf, 0, rxbytes); - - pwmd = owp->config->pwmd; - pwmcfg = owp->config->pwmcfg; - mch = owp->config->master_channel; - sch = owp->config->sample_channel; - - owp->reg.bit = 0; - owp->reg.final_timeslot = false; - owp->buf = rxbuf; - owp->reg.bytes = rxbytes; - - pwmcfg->period = ONEWIRE_ZERO_WIDTH + ONEWIRE_RECOVERY_WIDTH; - pwmcfg->callback = NULL; - pwmcfg->channels[mch].callback = NULL; - pwmcfg->channels[mch].mode = owp->config->pwmmode; - pwmcfg->channels[sch].callback = pwm_read_bit_cb; - pwmcfg->channels[sch].mode = PWM_OUTPUT_ACTIVE_LOW; - - ow_bus_active(owp); - osalSysLock(); - pwmEnableChannelI(pwmd, mch, ONEWIRE_ONE_WIDTH); - pwmEnableChannelI(pwmd, sch, ONEWIRE_SAMPLE_WIDTH); - pwmEnableChannelNotificationI(pwmd, sch); - osalThreadSuspendS(&owp->thread); - osalSysUnlock(); - - ow_bus_idle(owp); -} - -/** - * @brief Read some bites from slave device. - * - * @param[in] owp pointer to the @p onewireDriver object - * @param[in] txbuf pointer to the buffer with data to be written - * @param[in] txbytes amount of data to be written - * @param[in] pullup_time how long strong pull up must be activated. Set - * it to 0 if not needed. - */ -void onewireWrite(onewireDriver *owp, uint8_t *txbuf, - size_t txbytes, systime_t pullup_time) { - PWMDriver *pwmd; - PWMConfig *pwmcfg; - size_t mch, sch; - - osalDbgCheck((NULL != owp) && (NULL != txbuf)); - osalDbgCheck((txbytes > 0) && (txbytes <= ONEWIRE_MAX_TRANSACTION_LEN)); - osalDbgAssert(owp->reg.state == ONEWIRE_READY, "Invalid state"); -#if !ONEWIRE_USE_STRONG_PULLUP - osalDbgAssert(0 == pullup_time, - "Non zero time is valid only when strong pull enabled"); -#endif - - pwmd = owp->config->pwmd; - pwmcfg = owp->config->pwmcfg; - mch = owp->config->master_channel; - sch = owp->config->sample_channel; - - owp->buf = txbuf; - owp->reg.bit = 0; - owp->reg.final_timeslot = false; - owp->reg.bytes = txbytes; - - pwmcfg->period = ONEWIRE_ZERO_WIDTH + ONEWIRE_RECOVERY_WIDTH; - pwmcfg->callback = pwm_write_bit_cb; - pwmcfg->channels[mch].callback = NULL; - pwmcfg->channels[mch].mode = owp->config->pwmmode; - pwmcfg->channels[sch].callback = NULL; - pwmcfg->channels[sch].mode = PWM_OUTPUT_DISABLED; - -#if ONEWIRE_USE_STRONG_PULLUP - if (pullup_time > 0) { - owp->reg.state = ONEWIRE_PULL_UP; - owp->reg.need_pullup = true; - } -#endif - - ow_bus_active(owp); - osalSysLock(); - pwmEnablePeriodicNotificationI(pwmd); - osalThreadSuspendS(&owp->thread); - osalSysUnlock(); - - pwmDisablePeriodicNotification(pwmd); - ow_bus_idle(owp); - -#if ONEWIRE_USE_STRONG_PULLUP - if (pullup_time > 0) { - osalThreadSleep(pullup_time); - owp->config->pullup_release(); - owp->reg.state = ONEWIRE_READY; - } -#endif -} - -#if ONEWIRE_USE_SEARCH_ROM -/** - * @brief Performs tree search on bus. - * @note This function does internal 1-wire reset calls every search - * iteration. - * - * @param[in] owp pointer to a @p OWDriver object - * @param[out] result pointer to buffer for discovered ROMs - * @param[in] max_rom_cnt buffer size in ROMs count for overflow prevention - * - * @return Count of discovered ROMs. May be more than max_rom_cnt. - * @retval 0 no ROMs found or communication error occurred. - */ -size_t onewireSearchRom(onewireDriver *owp, uint8_t *result, - size_t max_rom_cnt) { - PWMDriver *pwmd; - PWMConfig *pwmcfg; - uint8_t cmd; - size_t mch, sch; - - osalDbgCheck(NULL != owp); - osalDbgAssert(ONEWIRE_READY == owp->reg.state, "Invalid state"); - osalDbgCheck((max_rom_cnt <= 256) && (max_rom_cnt > 0)); - - pwmd = owp->config->pwmd; - pwmcfg = owp->config->pwmcfg; - cmd = ONEWIRE_CMD_SEARCH_ROM; - mch = owp->config->master_channel; - sch = owp->config->sample_channel; - - search_clean_start(&owp->search_rom); - - do { - /* every search must be started from reset pulse */ - if (false == onewireReset(owp)) - return 0; - - /* initialize buffer to store result */ - if (owp->search_rom.reg.devices_found >= max_rom_cnt) - owp->search_rom.retbuf = result + 8*(max_rom_cnt-1); - else - owp->search_rom.retbuf = result + 8*owp->search_rom.reg.devices_found; - memset(owp->search_rom.retbuf, 0, 8); - - /* clean iteration state */ - search_clean_iteration(&owp->search_rom); - - /**/ - onewireWrite(&OWD1, &cmd, 1, 0); - - /* Reconfiguration always needed because of previous call onewireWrite.*/ - pwmcfg->period = ONEWIRE_ZERO_WIDTH + ONEWIRE_RECOVERY_WIDTH; - pwmcfg->callback = NULL; - pwmcfg->channels[mch].callback = NULL; - pwmcfg->channels[mch].mode = owp->config->pwmmode; - pwmcfg->channels[sch].callback = pwm_search_rom_cb; - pwmcfg->channels[sch].mode = PWM_OUTPUT_ACTIVE_LOW; - - ow_bus_active(owp); - osalSysLock(); - pwmEnableChannelI(pwmd, mch, ONEWIRE_ONE_WIDTH); - pwmEnableChannelI(pwmd, sch, ONEWIRE_SAMPLE_WIDTH); - pwmEnableChannelNotificationI(pwmd, sch); - osalThreadSuspendS(&owp->thread); - osalSysUnlock(); - - ow_bus_idle(owp); - - if (ONEWIRE_SEARCH_ROM_ERROR != owp->search_rom.reg.result) { - /* check CRC and return 0 (0 == error) if mismatch */ - if (owp->search_rom.retbuf[7] != onewireCRC(owp->search_rom.retbuf, 7)) - return 0; - /* store cached result for usage in next iteration */ - memcpy(owp->search_rom.prev_path, owp->search_rom.retbuf, 8); - } - } - while (ONEWIRE_SEARCH_ROM_SUCCESS == owp->search_rom.reg.result); - - /**/ - if (ONEWIRE_SEARCH_ROM_ERROR == owp->search_rom.reg.result) - return 0; - else - return owp->search_rom.reg.devices_found; -} -#endif /* ONEWIRE_USE_SEARCH_ROM */ - -/* - * Include test code (if enabled). - */ -#if ONEWIRE_SYNTH_SEARCH_TEST -#include "search_rom_synth.c" -#endif - -#endif /* HAL_USE_ONEWIRE */ - -/** @} */ diff --git a/ChibiOS_16.1.5/community/os/hal/src/hal_qei.c b/ChibiOS_16.1.5/community/os/hal/src/hal_qei.c deleted file mode 100644 index a2b7303..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/hal_qei.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2016 Martino Migliavacca - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/** - * @file hal_qei.c - * @brief QEI Driver code. - * - * @addtogroup QEI - * @{ - */ - -#include "hal.h" - -#if (HAL_USE_QEI == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief QEI Driver initialization. - * @note This function is implicitly invoked by @p halInit(), there is - * no need to explicitly initialize the driver. - * - * @init - */ -void qeiInit(void) { - - qei_lld_init(); -} - -/** - * @brief Initializes the standard part of a @p QEIDriver structure. - * - * @param[out] qeip pointer to the @p QEIDriver object - * - * @init - */ -void qeiObjectInit(QEIDriver *qeip) { - - qeip->state = QEI_STOP; - qeip->last = 0; - qeip->config = NULL; -} - -/** - * @brief Configures and activates the QEI peripheral. - * - * @param[in] qeip pointer to the @p QEIDriver object - * @param[in] config pointer to the @p QEIConfig object - * - * @api - */ -void qeiStart(QEIDriver *qeip, const QEIConfig *config) { - - osalDbgCheck((qeip != NULL) && (config != NULL)); - - osalSysLock(); - osalDbgAssert((qeip->state == QEI_STOP) || (qeip->state == QEI_READY), - "invalid state"); - qeip->config = config; - qei_lld_start(qeip); - qeip->state = QEI_READY; - osalSysUnlock(); -} - -/** - * @brief Deactivates the QEI peripheral. - * - * @param[in] qeip pointer to the @p QEIDriver object - * - * @api - */ -void qeiStop(QEIDriver *qeip) { - - osalDbgCheck(qeip != NULL); - - osalSysLock(); - osalDbgAssert((qeip->state == QEI_STOP) || (qeip->state == QEI_READY), - "invalid state"); - qei_lld_stop(qeip); - qeip->state = QEI_STOP; - osalSysUnlock(); -} - -/** - * @brief Enables the quadrature encoder interface. - * - * @param[in] qeip pointer to the @p QEIDriver object - * - * @api - */ -void qeiEnable(QEIDriver *qeip) { - - osalDbgCheck(qeip != NULL); - - osalSysLock(); - osalDbgAssert(qeip->state == QEI_READY, "invalid state"); - qei_lld_enable(qeip); - qeip->state = QEI_ACTIVE; - osalSysUnlock(); -} - -/** - * @brief Disables the quadrature encoder interface. - * - * @param[in] qeip pointer to the @p QEIDriver object - * - * @api - */ -void qeiDisable(QEIDriver *qeip) { - - osalDbgCheck(qeip != NULL); - - osalSysLock(); - osalDbgAssert((qeip->state == QEI_READY) || (qeip->state == QEI_ACTIVE), - "invalid state"); - qei_lld_disable(qeip); - qeip->state = QEI_READY; - osalSysUnlock(); -} - -/** - * @brief Returns the counter value. - * - * @param[in] qeip pointer to the @p QEIDriver object - * @return The current counter value. - * - * @api - */ -qeicnt_t qeiGetCount(QEIDriver *qeip) { - qeicnt_t cnt; - - osalSysLock(); - cnt = qeiGetCountI(qeip); - osalSysUnlock(); - - return cnt; -} - -/** - * @brief Returns the counter delta from last reading. - * - * @param[in] qeip pointer to the @p QEIDriver object - * @return The delta from last read. - * - * @api - */ -qeidelta_t qeiUpdate(QEIDriver *qeip) { - qeidelta_t diff; - - osalSysLock(); - diff = qeiUpdateI(qeip); - osalSysUnlock(); - - return diff; -} - -/** - * @brief Returns the counter delta from last reading. - * - * @param[in] qeip pointer to the @p QEIDriver object - * @return The delta from last read. - * - * @iclass - */ -qeidelta_t qeiUpdateI(QEIDriver *qeip) { - qeicnt_t cnt; - qeidelta_t delta; - - osalDbgCheckClassI(); - osalDbgCheck(qeip != NULL); - osalDbgAssert((qeip->state == QEI_READY) || (qeip->state == QEI_ACTIVE), - "invalid state"); - - cnt = qei_lld_get_count(qeip); - delta = cnt - qeip->last; - qeip->last = cnt; - - return delta; -} - -#endif /* HAL_USE_QEI == TRUE */ - -/** @} */ diff --git a/ChibiOS_16.1.5/community/os/hal/src/hal_rng.c b/ChibiOS_16.1.5/community/os/hal/src/hal_rng.c deleted file mode 100644 index 5ff6d2d..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/hal_rng.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - RNG for ChibiOS - Copyright (C) 2016 Stephane D'Alu - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/* - * Hardware Abstraction Layer for RNG Unit - */ -#include "hal.h" - -#if (HAL_USE_RNG == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief RNG Driver initialization. - * - * @init - */ -void rngInit(void) { - rng_lld_init(); -} - -/** - * @brief Initializes the standard part of a @p RNGDriver structure. - * - * @param[out] rngp Pointer to the @p RNGDriver object - * - * @init - */ -void rngObjectInit(RNGDriver *rngp) { - rngp->state = RNG_STOP; - rngp->config = NULL; -#if RNG_USE_MUTUAL_EXCLUSION == TRUE - osalMutexObjectInit(&rngp->mutex); -#endif -#if defined(RNG_DRIVER_EXT_INIT_HOOK) - RNG_DRIVER_EXT_INIT_HOOK(rngp); -#endif -} - -/** - * @brief Configures and activates the RNG peripheral. - * - * @param[in] rngp Pointer to the @p RNGDriver object - * @param[in] config Pointer to the @p RNGConfig object - * @p NULL if the low level driver implementation - * supports a default configuration - * - * @api - */ -void rngStart(RNGDriver *rngp, const RNGConfig *config) { - osalDbgCheck(rngp != NULL); - - osalSysLock(); - osalDbgAssert((rngp->state == RNG_STOP) || (rngp->state == RNG_READY), - "invalid state"); - rngp->config = config; - rng_lld_start(rngp); - rngp->state = RNG_READY; - osalSysUnlock(); -} - -/** - * @brief Deactivates the RNG peripheral. - * - * @param[in] rngp Pointer to the @p RNGDriver object - * - * @api - */ -void rngStop(RNGDriver *rngp) { - osalDbgCheck(rngp != NULL); - - osalSysLock(); - osalDbgAssert((rngp->state == RNG_STOP) || (rngp->state == RNG_READY), - "invalid state"); - rng_lld_stop(rngp); - rngp->state = RNG_STOP; - osalSysUnlock(); -} - -/** - * @brief Write random bytes - * @details Write the request number of bytes.. - * - * @param[in] rngp pointer to the @p RNGDriver object - * @param[in] buf the pointer to the buffer - * @param[in] n number of bytes to send - * @param[in] timeout timeout value - * - * @api - */ -msg_t rngWrite(RNGDriver *rngp, uint8_t *buf, size_t n, systime_t timeout) { - msg_t msg; - osalSysLock(); - msg = rngWriteI(rngp, buf, n, timeout); - osalSysUnlock(); - return msg; -} - -/** - * @brief Write random bytes - * @details Write the request number of bytes.. - * - * @param[in] rngp pointer to the @p RNGDriver object - * @param[in] buf the pointer to the buffer - * @param[in] n number of bytes to send - * @param[in] timeout timeout value - * - * @iclass - */ -msg_t rngWriteI(RNGDriver *rngp, uint8_t *buf, size_t n, systime_t timeout) { - osalDbgCheck((rngp != NULL) && (n > 0U) && (buf != NULL)); - osalDbgAssert(rngp->state == RNG_READY, "not ready"); - return rng_lld_write(rngp, buf, n, timeout); -} - - -#if (RNG_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__) -/** - * @brief Gains exclusive access to the RNG unit. - * @details This function tries to gain ownership to the RNG, if the RNG is - * already being used then the invoking thread is queued. - * @pre In order to use this function the option @p RNG_USE_MUTUAL_EXCLUSION - * must be enabled. - * - * @param[in] rngp pointer to the @p RNGDriver object - * - * @api - */ -void rngAcquireUnit(RNGDriver *rngp) { - osalDbgCheck(rngp != NULL); - - osalMutexLock(&rngp->mutex); -} - -/** - * @brief Releases exclusive access to the RNG unit. - * @pre In order to use this function the option @p RNG_USE_MUTUAL_EXCLUSION - * must be enabled. - * - * @param[in] rngp pointer to the @p RNGDriver object - * - * @api - */ -void rngReleaseUnit(RNGDriver *rngp) { - osalDbgCheck(rngp != NULL); - - osalMutexUnlock(&rngp->mutex); -} -#endif /* RNG_USE_MUTUAL_EXCLUSION == TRUE */ - -#endif /* HAL_USE_RNG */ diff --git a/ChibiOS_16.1.5/community/os/hal/src/hal_timcap.c b/ChibiOS_16.1.5/community/os/hal/src/hal_timcap.c deleted file mode 100644 index a352490..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/hal_timcap.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012,2013 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file timcap.c - * @brief TIMCAP Driver code. - * - * @addtogroup TIMCAP - * @{ - */ - -#include "hal_timcap.h" - -#if HAL_USE_TIMCAP || defined(__DOXYGEN__) - - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief TIMCAP Driver initialization. - * @note This function is implicitly invoked by @p halInit(), there is - * no need to explicitly initialize the driver. - * - * @init - */ -void timcapInit(void) { - - timcap_lld_init(); -} - -/** - * @brief Initializes the standard part of a @p TIMCAPDriver structure. - * - * @param[out] timcapp pointer to the @p TIMCAPDriver object - * - * @init - */ -void timcapObjectInit(TIMCAPDriver *timcapp) { - - timcapp->state = TIMCAP_STOP; - timcapp->config = NULL; -} - -/** - * @brief Configures and activates the TIMCAP peripheral. - * - * @param[in] timcapp pointer to the @p TIMCAPDriver object - * @param[in] config pointer to the @p TIMCAPConfig object - * - * @api - */ -void timcapStart(TIMCAPDriver *timcapp, const TIMCAPConfig *config) { - - osalDbgCheck((timcapp != NULL) && (config != NULL)); - - osalSysLock(); - osalDbgAssert((timcapp->state == TIMCAP_STOP) || (timcapp->state == TIMCAP_READY), - "invalid state"); - timcapp->config = config; - timcap_lld_start(timcapp); - timcapp->state = TIMCAP_READY; - osalSysUnlock(); -} - -/** - * @brief Deactivates the TIMCAP peripheral. - * - * @param[in] timcapp pointer to the @p TIMCAPDriver object - * - * @api - */ -void timcapStop(TIMCAPDriver *timcapp) { - - osalDbgCheck(timcapp != NULL); - - osalSysLock(); - osalDbgAssert((timcapp->state == TIMCAP_STOP) || (timcapp->state == TIMCAP_READY), - "invalid state"); - timcap_lld_stop(timcapp); - timcapp->state = TIMCAP_STOP; - osalSysUnlock(); -} - -/** - * @brief Enables the input capture. - * - * @param[in] timcapp pointer to the @p TIMCAPDriver object - * - * @api - */ -void timcapEnable(TIMCAPDriver *timcapp) { - - osalDbgCheck(timcapp != NULL); - - osalSysLock(); - osalDbgAssert(timcapp->state == TIMCAP_READY, "invalid state"); - timcap_lld_enable(timcapp); - timcapp->state = TIMCAP_WAITING; - osalSysUnlock(); -} - -/** - * @brief Disables the input capture. - * - * @param[in] timcapp pointer to the @p TIMCAPDriver object - * - * @api - */ -void timcapDisable(TIMCAPDriver *timcapp) { - - osalDbgCheck(timcapp != NULL); - - osalSysLock(); - osalDbgAssert((timcapp->state == TIMCAP_READY) || (timcapp->state == TIMCAP_WAITING) || - (timcapp->state == TIMCAP_ACTIVE) || (timcapp->state == TIMCAP_IDLE), - "invalid state"); - timcap_lld_disable(timcapp); - timcapp->state = TIMCAP_READY; - osalSysUnlock(); -} - -#endif /* HAL_USE_TIMCAP */ - -/** @} */ diff --git a/ChibiOS_16.1.5/community/os/hal/src/hal_usb_hid.c b/ChibiOS_16.1.5/community/os/hal/src/hal_usb_hid.c deleted file mode 100644 index 56be9b7..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/hal_usb_hid.c +++ /dev/null @@ -1,581 +0,0 @@ -/* - ChibiOS - Copyright (C) 2016 Jonathan Struebel - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/** - * @file hal_usb_hid.c - * @brief USB HID Driver code. - * - * @addtogroup USB_HID - * @{ - */ - -#include "hal.h" - -#if (HAL_USE_USB_HID == TRUE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -static uint16_t get_hword(uint8_t *p) { - uint16_t hw; - - hw = (uint16_t)*p++; - hw |= (uint16_t)*p << 8U; - return hw; -} - -/* - * Interface implementation. - */ - -static size_t write(void *ip, const uint8_t *bp, size_t n) { - - if (usbGetDriverStateI(((USBHIDDriver *)ip)->config->usbp) != USB_ACTIVE) { - return 0; - } - - return obqWriteTimeout(&((USBHIDDriver *)ip)->obqueue, bp, - n, TIME_INFINITE); -} - -static size_t read(void *ip, uint8_t *bp, size_t n) { - - if (usbGetDriverStateI(((USBHIDDriver *)ip)->config->usbp) != USB_ACTIVE) { - return 0; - } - - return ibqReadTimeout(&((USBHIDDriver *)ip)->ibqueue, bp, - n, TIME_INFINITE); -} - -static msg_t put(void *ip, uint8_t b) { - - if (usbGetDriverStateI(((USBHIDDriver *)ip)->config->usbp) != USB_ACTIVE) { - return MSG_RESET; - } - - return obqPutTimeout(&((USBHIDDriver *)ip)->obqueue, b, TIME_INFINITE); -} - -static msg_t get(void *ip) { - - if (usbGetDriverStateI(((USBHIDDriver *)ip)->config->usbp) != USB_ACTIVE) { - return MSG_RESET; - } - - return ibqGetTimeout(&((USBHIDDriver *)ip)->ibqueue, TIME_INFINITE); -} - -static msg_t putt(void *ip, uint8_t b, systime_t timeout) { - - if (usbGetDriverStateI(((USBHIDDriver *)ip)->config->usbp) != USB_ACTIVE) { - return MSG_RESET; - } - - return obqPutTimeout(&((USBHIDDriver *)ip)->obqueue, b, timeout); -} - -static msg_t gett(void *ip, systime_t timeout) { - - if (usbGetDriverStateI(((USBHIDDriver *)ip)->config->usbp) != USB_ACTIVE) { - return MSG_RESET; - } - - return ibqGetTimeout(&((USBHIDDriver *)ip)->ibqueue, timeout); -} - -static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t timeout) { - - if (usbGetDriverStateI(((USBHIDDriver *)ip)->config->usbp) != USB_ACTIVE) { - return 0; - } - - return obqWriteTimeout(&((USBHIDDriver *)ip)->obqueue, bp, n, timeout); -} - -static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t timeout) { - - if (usbGetDriverStateI(((USBHIDDriver *)ip)->config->usbp) != USB_ACTIVE) { - return 0; - } - - return ibqReadTimeout(&((USBHIDDriver *)ip)->ibqueue, bp, n, timeout); -} - -static void flush(void *ip) { - - obqFlush(&((USBHIDDriver *)ip)->obqueue); -} - -static const struct USBHIDDriverVMT vmt = { - write, read, put, get, - putt, gett, writet, readt, - flush -}; - -/** - * @brief Notification of empty buffer released into the input buffers queue. - * - * @param[in] bqp the buffers queue pointer. - */ -static void ibnotify(io_buffers_queue_t *bqp) { - USBHIDDriver *uhdp = bqGetLinkX(bqp); - - /* If the USB driver is not in the appropriate state then transactions - must not be started.*/ - if ((usbGetDriverStateI(uhdp->config->usbp) != USB_ACTIVE) || - (uhdp->state != HID_READY)) { - return; - } - - /* Checking if there is already a transaction ongoing on the endpoint.*/ - if (!usbGetReceiveStatusI(uhdp->config->usbp, uhdp->config->int_out)) { - /* Trying to get a free buffer.*/ - uint8_t *buf = ibqGetEmptyBufferI(&uhdp->ibqueue); - if (buf != NULL) { - /* Buffer found, starting a new transaction.*/ - usbStartReceiveI(uhdp->config->usbp, uhdp->config->int_out, - buf, SERIAL_USB_BUFFERS_SIZE); - } - } -} - -/** - * @brief Notification of filled buffer inserted into the output buffers queue. - * - * @param[in] bqp the buffers queue pointer. - */ -static void obnotify(io_buffers_queue_t *bqp) { - size_t n; - USBHIDDriver *uhdp = bqGetLinkX(bqp); - - /* If the USB driver is not in the appropriate state then transactions - must not be started.*/ - if ((usbGetDriverStateI(uhdp->config->usbp) != USB_ACTIVE) || - (uhdp->state != HID_READY)) { - return; - } - - /* Checking if there is already a transaction ongoing on the endpoint.*/ - if (!usbGetTransmitStatusI(uhdp->config->usbp, uhdp->config->int_in)) { - /* Trying to get a full buffer.*/ - uint8_t *buf = obqGetFullBufferI(&uhdp->obqueue, &n); - if (buf != NULL) { - /* Buffer found, starting a new transaction.*/ - usbStartTransmitI(uhdp->config->usbp, uhdp->config->int_in, buf, n); - } - } -} - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief USB HID Driver initialization. - * @note This function is implicitly invoked by @p halInit(), there is - * no need to explicitly initialize the driver. - * - * @init - */ -void hidInit(void) { -} - -/** - * @brief Initializes a generic full duplex USB HID driver object. - * @details The HW dependent part of the initialization has to be performed - * outside, usually in the hardware initialization code. - * - * @param[out] uhdp pointer to a @p USBHIDDriver structure - * - * @init - */ -void hidObjectInit(USBHIDDriver *uhdp) { - - uhdp->vmt = &vmt; - osalEventObjectInit(&uhdp->event); - uhdp->state = HID_STOP; - ibqObjectInit(&uhdp->ibqueue, uhdp->ib, - USB_HID_BUFFERS_SIZE, USB_HID_BUFFERS_NUMBER, - ibnotify, uhdp); - obqObjectInit(&uhdp->obqueue, uhdp->ob, - USB_HID_BUFFERS_SIZE, USB_HID_BUFFERS_NUMBER, - obnotify, uhdp); -} - -/** - * @brief Configures and starts the driver. - * - * @param[in] uhdp pointer to a @p USBHIDDriver object - * @param[in] config the USB HID driver configuration - * - * @api - */ -void hidStart(USBHIDDriver *uhdp, const USBHIDConfig *config) { - USBDriver *usbp = config->usbp; - - osalDbgCheck(uhdp != NULL); - - osalSysLock(); - osalDbgAssert((uhdp->state == HID_STOP) || (uhdp->state == HID_READY), - "invalid state"); - usbp->in_params[config->int_in - 1U] = uhdp; - usbp->out_params[config->int_out - 1U] = uhdp; - uhdp->config = config; - uhdp->state = HID_READY; - osalSysUnlock(); -} - -/** - * @brief Stops the driver. - * @details Any thread waiting on the driver's queues will be awakened with - * the message @p MSG_RESET. - * - * @param[in] uhdp pointer to a @p USBHIDDriver object - * - * @api - */ -void hidStop(USBHIDDriver *uhdp) { - USBDriver *usbp = uhdp->config->usbp; - - osalDbgCheck(uhdp != NULL); - - osalSysLock(); - osalDbgAssert((uhdp->state == HID_STOP) || (uhdp->state == HID_READY), - "invalid state"); - - /* Driver in stopped state.*/ - usbp->in_params[uhdp->config->int_in - 1U] = NULL; - usbp->out_params[uhdp->config->int_out - 1U] = NULL; - uhdp->state = HID_STOP; - - /* Enforces a disconnection.*/ - hidDisconnectI(uhdp); - osalOsRescheduleS(); - osalSysUnlock(); -} - -/** - * @brief USB device disconnection handler. - * @note If this function is not called from an ISR then an explicit call - * to @p osalOsRescheduleS() in necessary afterward. - * - * @param[in] uhdp pointer to a @p USBHIDDriver object - * - * @iclass - */ -void hidDisconnectI(USBHIDDriver *uhdp) { - - /* Queues reset in order to signal the driver stop to the application.*/ - chnAddFlagsI(uhdp, CHN_DISCONNECTED); - ibqResetI(&uhdp->ibqueue); - obqResetI(&uhdp->obqueue); -} - -/** - * @brief USB device configured handler. - * - * @param[in] uhdp pointer to a @p USBHIDDriver object - * - * @iclass - */ -void hidConfigureHookI(USBHIDDriver *uhdp) { - uint8_t *buf; - - ibqResetI(&uhdp->ibqueue); - obqResetI(&uhdp->obqueue); - chnAddFlagsI(uhdp, CHN_CONNECTED); - - /* Starts the first OUT transaction immediately.*/ - buf = ibqGetEmptyBufferI(&uhdp->ibqueue); - - osalDbgAssert(buf != NULL, "no free buffer"); - - usbStartReceiveI(uhdp->config->usbp, uhdp->config->int_out, - buf, USB_HID_BUFFERS_SIZE); -} - -/** - * @brief Default requests hook. - * @details Applications wanting to use the USB HID driver can use - * this function at the end of the application specific - * requests hook. The HID_* requests handled here do not - * transfer any data to the application. - * The following requests are handled: - * - HID_GET_IDLE. - * - HID_GET_PROTOCOL. - * - HID_SET_REPORT. - * - HID_SET_IDLE. - * - HID_SET_PROTOCOL. - * - USB_REQ_GET_DESCRIPTOR. - * . - * - * @param[in] usbp pointer to the @p USBDriver object - * @return The hook status. - * @retval true Message handled internally. - * @retval false Message not handled. - */ -bool hidRequestsHook(USBDriver *usbp) { - const USBDescriptor *dp; - - if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) { - switch (usbp->setup[1]) { - case HID_GET_IDLE: - usbSetupTransfer(usbp, NULL, 0, NULL); - return true; - case HID_GET_PROTOCOL: - return true; - case HID_SET_REPORT: - usbSetupTransfer(usbp, NULL, 0, NULL); - return true; - case HID_SET_IDLE: - usbSetupTransfer(usbp, NULL, 0, NULL); - return true; - case HID_SET_PROTOCOL: - return true; - default: - return false; - } - } - - /* GET_DESCRIPTOR from interface not handled by default so handle it here */ - if (((usbp->setup[0] & USB_RTYPE_DIR_MASK) == USB_RTYPE_DIR_DEV2HOST) && - ((usbp->setup[0] & USB_RTYPE_RECIPIENT_MASK) == USB_RTYPE_RECIPIENT_INTERFACE)) { - switch (usbp->setup[1]) { - case USB_REQ_GET_DESCRIPTOR: - dp = usbp->config->get_descriptor_cb(usbp, usbp->setup[3], usbp->setup[2], - get_hword(&usbp->setup[4])); - if (dp == NULL) - return false; - - usbSetupTransfer(usbp, (uint8_t *)dp->ud_string, dp->ud_size, NULL); - return true; - default: - return false; - } - } - return false; -} - -/** - * @brief Default data transmitted callback. - * @details The application must use this function as callback for the IN - * data endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep IN endpoint number - */ -void hidDataTransmitted(USBDriver *usbp, usbep_t ep) { - uint8_t *buf; - size_t n; - USBHIDDriver *uhdp = usbp->in_params[ep - 1U]; - - if (uhdp == NULL) { - return; - } - - osalSysLockFromISR(); - - /* Signaling that space is available in the output queue.*/ - chnAddFlagsI(uhdp, CHN_OUTPUT_EMPTY); - - /* Freeing the buffer just transmitted, if it was not a zero size packet.*/ - if (usbp->epc[ep]->in_state->txsize > 0U) { - obqReleaseEmptyBufferI(&uhdp->obqueue); - } - - /* Checking if there is a buffer ready for transmission.*/ - buf = obqGetFullBufferI(&uhdp->obqueue, &n); - - if (buf != NULL) { - /* The endpoint cannot be busy, we are in the context of the callback, - so it is safe to transmit without a check.*/ - usbStartTransmitI(usbp, ep, buf, n); - } - else if ((usbp->epc[ep]->in_state->txsize > 0U) && - ((usbp->epc[ep]->in_state->txsize & - ((size_t)usbp->epc[ep]->in_maxsize - 1U)) == 0U)) { - /* Transmit zero sized packet in case the last one has maximum allowed - size. Otherwise the recipient may expect more data coming soon and - not return buffered data to app. See section 5.8.3 Bulk Transfer - Packet Size Constraints of the USB Specification document.*/ - usbStartTransmitI(usbp, ep, usbp->setup, 0); - - } - else { - /* Nothing to transmit.*/ - } - - osalSysUnlockFromISR(); -} - -/** - * @brief Default data received callback. - * @details The application must use this function as callback for the OUT - * data endpoint. - * - * @param[in] usbp pointer to the @p USBDriver object - * @param[in] ep OUT endpoint number - */ -void hidDataReceived(USBDriver *usbp, usbep_t ep) { - uint8_t *buf; - USBHIDDriver *uhdp = usbp->out_params[ep - 1U]; - - if (uhdp == NULL) { - return; - } - - osalSysLockFromISR(); - - /* Signaling that data is available in the input queue.*/ - chnAddFlagsI(uhdp, CHN_INPUT_AVAILABLE); - - /* Posting the filled buffer in the queue.*/ - ibqPostFullBufferI(&uhdp->ibqueue, - usbGetReceiveTransactionSizeX(uhdp->config->usbp, ep)); - - /* The endpoint cannot be busy, we are in the context of the callback, - so a packet is in the buffer for sure. Trying to get a free buffer - for the next transaction.*/ - buf = ibqGetEmptyBufferI(&uhdp->ibqueue); - if (buf != NULL) { - /* Buffer found, starting a new transaction.*/ - usbStartReceiveI(uhdp->config->usbp, ep, buf, USB_HID_BUFFERS_SIZE); - } - - osalSysUnlockFromISR(); -} - -/** - * @brief Write HID Report - * @details The function writes data from a buffer to an output queue. The - * operation completes when the specified amount of data has been - * transferred or if the queue has been reset. - * - * @param[in] uhdp pointer to the @p USBHIDDriver object - * @param[in] bp pointer to the report data buffer - * @param[in] n the maximum amount of data to be transferred, the - * value 0 is reserved - * @return The number of bytes effectively transferred. - * @retval 0 if a timeout occurred. - * - * @api - */ -size_t hidWriteReport(USBHIDDriver *uhdp, uint8_t *bp, size_t n) { - size_t val; - - val = uhdp->vmt->write(uhdp, bp, n); - - if (val > 0) - uhdp->vmt->flush(uhdp); - - return val; -} - -/** - * @brief Write HID report with timeout - * @details The function writes data from a buffer to an output queue. The - * operation completes when the specified amount of data has been - * transferred or after the specified timeout or if the queue has - * been reset. - * - * @param[in] uhdp pointer to the @p USBHIDDriver object - * @param[in] bp pointer to the report data buffer - * @param[in] n the maximum amount of data to be transferred, the - * value 0 is reserved - * @param[in] timeout the number of ticks before the operation timeouts, - * the following special values are allowed: - * - @a TIME_IMMEDIATE immediate timeout. - * - @a TIME_INFINITE no timeout. - * . - * @return The number of bytes effectively transferred. - * @retval 0 if a timeout occurred. - * - * @api - */ -size_t hidWriteReportt(USBHIDDriver *uhdp, uint8_t *bp, size_t n, systime_t timeout) { - size_t val; - - val = uhdp->vmt->writet(uhdp, bp, n, timeout); - - if (val > 0) - uhdp->vmt->flush(uhdp); - - return val; -} - -/** - * @brief Read HID report - * @details The function reads data from an input queue into a buffer. - * The operation completes when the specified amount of data has been - * transferred or if the queue has been reset. - * - * @param[in] uhdp pointer to the @p input_buffers_queue_t object - * @param[out] bp pointer to the data buffer - * @param[in] n the maximum amount of data to be transferred, the - * value 0 is reserved - * @return The number of bytes effectively transferred. - * @retval 0 if a timeout occurred. - * - * @api - */ -size_t hidReadReport(USBHIDDriver *uhdp, uint8_t *bp, size_t n) { - - return uhdp->vmt->read(uhdp, bp, n); -} - -/** - * @brief Read HID report with timeout - * @details The function reads data from an input queue into a buffer. - * The operation completes when the specified amount of data has been - * transferred or after the specified timeout or if the queue has - * been reset. - * - * @param[in] uhdp pointer to the @p input_buffers_queue_t object - * @param[out] bp pointer to the data buffer - * @param[in] n the maximum amount of data to be transferred, the - * value 0 is reserved - * @param[in] timeout the number of ticks before the operation timeouts, - * the following special values are allowed: - * - @a TIME_IMMEDIATE immediate timeout. - * - @a TIME_INFINITE no timeout. - * . - * @return The number of bytes effectively transferred. - * @retval 0 if a timeout occurred. - * - * @api - */ -size_t hidReadReportt(USBHIDDriver *uhdp, uint8_t *bp, size_t n, systime_t timeout) { - - return uhdp->vmt->readt(uhdp, bp, n, timeout); -} - -#endif /* HAL_USE_USB_HID == TRUE */ - -/** @} */ diff --git a/ChibiOS_16.1.5/community/os/hal/src/hal_usbh.c b/ChibiOS_16.1.5/community/os/hal/src/hal_usbh.c deleted file mode 100644 index 1caa183..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/hal_usbh.c +++ /dev/null @@ -1,1395 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio - Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail) - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#include "hal.h" - -#if HAL_USE_USBH - -#include "usbh/dev/hub.h" -#include "usbh/internal.h" -#include - -#if USBH_DEBUG_ENABLE_TRACE -#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define udbgf(f, ...) do {} while(0) -#define udbg(f, ...) do {} while(0) -#endif - -#if USBH_DEBUG_ENABLE_INFO -#define uinfof(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define uinfo(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define uinfof(f, ...) do {} while(0) -#define uinfo(f, ...) do {} while(0) -#endif - -#if USBH_DEBUG_ENABLE_WARNINGS -#define uwarnf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define uwarn(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define uwarnf(f, ...) do {} while(0) -#define uwarn(f, ...) do {} while(0) -#endif - -#if USBH_DEBUG_ENABLE_ERRORS -#define uerrf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define uerr(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define uerrf(f, ...) do {} while(0) -#define uerr(f, ...) do {} while(0) -#endif - -#if STM32_USBH_USE_OTG1 -USBHDriver USBHD1; -#endif -#if STM32_USBH_USE_OTG2 -USBHDriver USBHD2; -#endif - - -static void _classdriver_process_device(usbh_device_t *dev); -static bool _classdriver_load(usbh_device_t *dev, uint8_t class, - uint8_t subclass, uint8_t protocol, uint8_t *descbuff, uint16_t rem); - - -/*===========================================================================*/ -/* Checks. */ -/*===========================================================================*/ - -static inline void _check_dev(usbh_device_t *dev) { - osalDbgCheck(dev); - //TODO: add more checks. -} - -static inline void _check_ep(usbh_ep_t *ep) { - osalDbgCheck(ep != 0); - _check_dev(ep->device); - osalDbgCheck(ep->type <= 3); - //TODO: add more checks. -} - -static inline void _check_urb(usbh_urb_t *urb) { - osalDbgCheck(urb != 0); - _check_ep(urb->ep); - osalDbgCheck((urb->buff != NULL) || (urb->requestedLength == 0)); - //TODO: add more checks. -} - -/*===========================================================================*/ -/* Main driver API. */ -/*===========================================================================*/ - -void usbhObjectInit(USBHDriver *usbh) { - memset(usbh, 0, sizeof(*usbh)); - usbh->status = USBH_STATUS_STOPPED; -#if HAL_USBH_USE_HUB - INIT_LIST_HEAD(&usbh->hubs); - _usbhub_port_object_init(&usbh->rootport, usbh, 0, 1); -#else - _usbhub_port_object_init(&usbh->rootport, usbh, 1); -#endif -} - -void usbhInit(void) { -#if HAL_USBH_USE_HUB - uint8_t i; - for (i = 0; i < HAL_USBHHUB_MAX_INSTANCES; i++) { - usbhhubObjectInit(&USBHHUBD[i]); - } -#endif - usbh_lld_init(); -} - -void usbhStart(USBHDriver *usbh) { - usbDbgInit(usbh); - - osalSysLock(); - osalDbgAssert((usbh->status == USBH_STATUS_STOPPED) || (usbh->status == USBH_STATUS_STARTED), - "invalid state"); - usbh_lld_start(usbh); - usbh->status = USBH_STATUS_STARTED; - osalOsRescheduleS(); - osalSysUnlock(); -} - - -void usbhStop(USBHDriver *usbh) { - //TODO: implement - (void)usbh; -} -void usbhSuspend(USBHDriver *usbh) { - //TODO: implement - (void)usbh; -} -void usbhResume(USBHDriver *usbh) { - //TODO: implement - (void)usbh; -} - -/*===========================================================================*/ -/* Endpoint API. */ -/*===========================================================================*/ - -void usbhEPObjectInit(usbh_ep_t *ep, usbh_device_t *dev, const usbh_endpoint_descriptor_t *desc) { - osalDbgCheck(ep); - _check_dev(dev); - osalDbgCheck(desc); - - memset(ep, 0, sizeof(*ep)); - ep->device = dev; - ep->wMaxPacketSize = desc->wMaxPacketSize; - ep->address = desc->bEndpointAddress & 0x0F; - ep->type = (usbh_eptype_t) (desc->bmAttributes & 0x03); - if (ep->type != USBH_EPTYPE_CTRL) { - ep->in = (desc->bEndpointAddress & 0x80) ? TRUE : FALSE; - } - ep->bInterval = desc->bInterval; - - /* low-level part */ - usbh_lld_ep_object_init(ep); - - ep->status = USBH_EPSTATUS_CLOSED; -} - - -static void _ep0_object_init(usbh_device_t *dev, uint16_t wMaxPacketSize) { - const usbh_endpoint_descriptor_t ep0_descriptor = { - 7, //bLength - 5, //bDescriptorType - 0, //bEndpointAddress - 0, //bmAttributes - wMaxPacketSize, - 0, //bInterval - }; - usbhEPObjectInit(&dev->ctrl, dev, &ep0_descriptor); - usbhEPSetName(&dev->ctrl, "DEV[CTRL]"); -} - - -/*===========================================================================*/ -/* URB API. */ -/*===========================================================================*/ - -void usbhURBObjectInit(usbh_urb_t *urb, usbh_ep_t *ep, usbh_completion_cb callback, - void *user, void *buff, uint32_t len) { - - osalDbgCheck(urb != 0); - _check_ep(ep); - - /* initialize the common part: */ - urb->ep = ep; - urb->callback = callback; - urb->userData = user; - urb->buff = buff; - urb->requestedLength = len; - urb->actualLength = 0; - urb->status = USBH_URBSTATUS_INITIALIZED; - urb->waitingThread = 0; - urb->abortingThread = 0; - - /* initialize the ll part: */ - usbh_lld_urb_object_init(urb); -} - -void usbhURBObjectResetI(usbh_urb_t *urb) { - osalDbgAssert(!usbhURBIsBusy(urb), "invalid status"); - - osalDbgCheck((urb->waitingThread == 0) && (urb->abortingThread == 0)); - - urb->actualLength = 0; - urb->status = USBH_URBSTATUS_INITIALIZED; - - /* reset the ll part: */ - usbh_lld_urb_object_reset(urb); -} - -void usbhURBSubmitI(usbh_urb_t *urb) { - osalDbgCheckClassI(); - _check_urb(urb); - osalDbgAssert(urb->status == USBH_URBSTATUS_INITIALIZED, "invalid status"); - usbh_ep_t *const ep = urb->ep; - if (ep->status == USBH_EPSTATUS_HALTED) { - _usbh_urb_completeI(urb, USBH_URBSTATUS_STALL); - return; - } - if (ep->status != USBH_EPSTATUS_OPEN) { - _usbh_urb_completeI(urb, USBH_URBSTATUS_DISCONNECTED); - return; - } - if (!(usbhDeviceGetPort(ep->device)->status & USBH_PORTSTATUS_ENABLE)) { - _usbh_urb_completeI(urb, USBH_URBSTATUS_DISCONNECTED); - return; - } - urb->status = USBH_URBSTATUS_PENDING; - usbh_lld_urb_submit(urb); -} - -bool _usbh_urb_abortI(usbh_urb_t *urb, usbh_urbstatus_t status) { - osalDbgCheckClassI(); - _check_urb(urb); - - switch (urb->status) { -/* case USBH_URBSTATUS_UNINITIALIZED: - * case USBH_URBSTATUS_INITIALIZED: - * case USBH_URBSTATUS_ERROR: - * case USBH_URBSTATUS_TIMEOUT: - * case USBH_URBSTATUS_CANCELLED: - * case USBH_URBSTATUS_STALL: - * case USBH_URBSTATUS_DISCONNECTED: - * case USBH_URBSTATUS_OK: */ - default: - /* already finished */ - _usbh_urb_completeI(urb, status); - return TRUE; - -// case USBH_URBSTATUS_QUEUED: - case USBH_URBSTATUS_PENDING: - return usbh_lld_urb_abort(urb, status); - } -} - -void _usbh_urb_abort_and_waitS(usbh_urb_t *urb, usbh_urbstatus_t status) { - osalDbgCheckClassS(); - _check_urb(urb); - - if (_usbh_urb_abortI(urb, status) == FALSE) { - uwarn("URB wasn't aborted immediately, suspend"); - osalThreadSuspendS(&urb->abortingThread); - urb->abortingThread = 0; - } else { - osalOsRescheduleS(); - } - uwarn("URB aborted"); -} - -bool usbhURBCancelI(usbh_urb_t *urb) { - return _usbh_urb_abortI(urb, USBH_URBSTATUS_CANCELLED); -} - -void usbhURBCancelAndWaitS(usbh_urb_t *urb) { - _usbh_urb_abort_and_waitS(urb, USBH_URBSTATUS_CANCELLED); -} - -msg_t usbhURBWaitTimeoutS(usbh_urb_t *urb, systime_t timeout) { - msg_t ret; - - osalDbgCheckClassS(); - _check_urb(urb); - - switch (urb->status) { - case USBH_URBSTATUS_INITIALIZED: - case USBH_URBSTATUS_PENDING: -// case USBH_URBSTATUS_QUEUED: - ret = osalThreadSuspendTimeoutS(&urb->waitingThread, timeout); - urb->waitingThread = 0; - break; - - case USBH_URBSTATUS_OK: - ret = MSG_OK; - osalOsRescheduleS(); - break; - -/* case USBH_URBSTATUS_UNINITIALIZED: - * case USBH_URBSTATUS_ERROR: - * case USBH_URBSTATUS_TIMEOUT: - * case USBH_URBSTATUS_CANCELLED: - * case USBH_URBSTATUS_STALL: - * case USBH_URBSTATUS_DISCONNECTED: */ - default: - ret = MSG_RESET; - osalOsRescheduleS(); - break; - } - return ret; -} - -msg_t usbhURBSubmitAndWaitS(usbh_urb_t *urb, systime_t timeout) { - msg_t ret; - - osalDbgCheckClassS(); - _check_urb(urb); - - usbhURBSubmitI(urb); - ret = usbhURBWaitTimeoutS(urb, timeout); - if (ret == MSG_TIMEOUT) - _usbh_urb_abort_and_waitS(urb, USBH_URBSTATUS_TIMEOUT); - - return ret; -} - -static inline msg_t _wakeup_message(usbh_urbstatus_t status) { - if (status == USBH_URBSTATUS_OK) return MSG_OK; - if (status == USBH_URBSTATUS_TIMEOUT) return MSG_TIMEOUT; - return MSG_RESET; -} - -void _usbh_urb_completeI(usbh_urb_t *urb, usbh_urbstatus_t status) { - osalDbgCheckClassI(); - _check_urb(urb); - urb->status = status; - osalThreadResumeI(&urb->waitingThread, _wakeup_message(status)); - osalThreadResumeI(&urb->abortingThread, MSG_RESET); - if (urb->callback) - urb->callback(urb); -} - -/*===========================================================================*/ -/* Synchronous API. */ -/*===========================================================================*/ - -usbh_urbstatus_t usbhBulkTransfer(usbh_ep_t *ep, - void *data, - uint32_t len, - uint32_t *actual_len, - systime_t timeout) { - - osalDbgCheck(ep != NULL); - osalDbgCheck((data != NULL) || (len == 0)); - osalDbgAssert(ep->type == USBH_EPTYPE_BULK, "wrong ep"); - - usbh_urb_t urb; - usbhURBObjectInit(&urb, ep, 0, 0, data, len); - - osalSysLock(); - usbhURBSubmitAndWaitS(&urb, timeout); - osalSysUnlock(); - - if (actual_len != NULL) - *actual_len = urb.actualLength; - - return urb.status; -} - -usbh_urbstatus_t usbhControlRequestExtended(usbh_device_t *dev, - const usbh_control_request_t *req, - uint8_t *buff, - uint32_t *actual_len, - systime_t timeout) { - - _check_dev(dev); - osalDbgCheck(req != NULL); - - usbh_urb_t urb; - - usbhURBObjectInit(&urb, &dev->ctrl, 0, 0, buff, req->wLength); - urb.setup_buff = req; - - osalSysLock(); - usbhURBSubmitAndWaitS(&urb, timeout); - osalSysUnlock(); - - if (actual_len != NULL) - *actual_len = urb.actualLength; - - return urb.status; -} - -usbh_urbstatus_t usbhControlRequest(usbh_device_t *dev, - uint8_t bmRequestType, - uint8_t bRequest, - uint16_t wValue, - uint16_t wIndex, - uint16_t wLength, - uint8_t *buff) { - - const USBH_DEFINE_BUFFER(usbh_control_request_t, req) = { - bmRequestType, - bRequest, - wValue, - wIndex, - wLength - }; - return usbhControlRequestExtended(dev, &req, buff, NULL, MS2ST(1000)); -} - -/*===========================================================================*/ -/* Standard request helpers. */ -/*===========================================================================*/ - -#define USBH_GET_DESCRIPTOR(type, value, index) \ - USBH_STANDARDIN(type, \ - USBH_REQ_GET_DESCRIPTOR, \ - value, \ - index) \ - -#define USBH_GETDEVICEDESCRIPTOR \ - USBH_GET_DESCRIPTOR(USBH_REQTYPE_DEVICE, (USBH_DT_DEVICE << 8) | 0, 0) - -#define USBH_GETCONFIGURATIONDESCRIPTOR(index) \ - USBH_GET_DESCRIPTOR(USBH_REQTYPE_DEVICE, (USBH_DT_CONFIG << 8) | index, 0) - -#define USBH_GETSTRINGDESCRIPTOR(index, langID) \ - USBH_GET_DESCRIPTOR(USBH_REQTYPE_DEVICE, (USBH_DT_STRING << 8) | index, langID) - -bool usbhStdReqGetDeviceDescriptor(usbh_device_t *dev, - uint16_t wLength, - uint8_t *buf) { - usbh_device_descriptor_t *desc; - usbh_urbstatus_t ret = usbhControlRequest(dev, USBH_GETDEVICEDESCRIPTOR, wLength, buf); - desc = (usbh_device_descriptor_t *)buf; - if ((ret != USBH_URBSTATUS_OK) - || (desc->bLength != USBH_DT_DEVICE_SIZE) - || (desc->bDescriptorType != USBH_DT_DEVICE)) { - return HAL_FAILED; - } - return HAL_SUCCESS; -} - -bool usbhStdReqGetConfigurationDescriptor(usbh_device_t *dev, - uint8_t index, - uint16_t wLength, - uint8_t *buf) { - usbh_urbstatus_t ret = usbhControlRequest(dev, USBH_GETCONFIGURATIONDESCRIPTOR(index), wLength, buf); - usbh_config_descriptor_t *const desc = (usbh_config_descriptor_t *)buf; - if ((ret != USBH_URBSTATUS_OK) - || (desc->bLength < USBH_DT_CONFIG_SIZE) - || (desc->bDescriptorType != USBH_DT_CONFIG)) { - return HAL_FAILED; - } - return HAL_SUCCESS; -} - -bool usbhStdReqGetStringDescriptor(usbh_device_t *dev, - uint8_t index, - uint16_t langID, - uint16_t wLength, - uint8_t *buf) { - - osalDbgAssert(wLength >= USBH_DT_STRING_SIZE, "wrong size"); - usbh_string_descriptor_t *desc = (usbh_string_descriptor_t *)buf; - usbh_urbstatus_t ret = usbhControlRequest(dev, USBH_GETSTRINGDESCRIPTOR(index, langID), wLength, buf); - if ((ret != USBH_URBSTATUS_OK) - || (desc->bLength < USBH_DT_STRING_SIZE) - || (desc->bDescriptorType != USBH_DT_STRING)) { - return HAL_FAILED; - } - return HAL_SUCCESS; -} - - - -#define USBH_SET_INTERFACE(interface, alt) \ - USBH_STANDARDOUT(USBH_REQTYPE_INTERFACE, \ - USBH_REQ_SET_INTERFACE, \ - alt, \ - interface) \ - -#define USBH_GET_INTERFACE(interface) \ - USBH_STANDARDIN(USBH_REQTYPE_INTERFACE, \ - USBH_REQ_GET_INTERFACE, \ - 0, \ - interface) \ - -bool usbhStdReqSetInterface(usbh_device_t *dev, - uint8_t bInterfaceNumber, - uint8_t bAlternateSetting) { - - usbh_urbstatus_t ret = usbhControlRequest(dev, USBH_SET_INTERFACE(bInterfaceNumber, bAlternateSetting), 0, NULL); - if (ret != USBH_URBSTATUS_OK) - return HAL_FAILED; - - return HAL_SUCCESS; -} - -bool usbhStdReqGetInterface(usbh_device_t *dev, - uint8_t bInterfaceNumber, - uint8_t *bAlternateSetting) { - - USBH_DEFINE_BUFFER(uint8_t, alt); - - usbh_urbstatus_t ret = usbhControlRequest(dev, USBH_GET_INTERFACE(bInterfaceNumber), 1, &alt); - if (ret != USBH_URBSTATUS_OK) - return HAL_FAILED; - - *bAlternateSetting = alt; - return HAL_SUCCESS; -} - - -/*===========================================================================*/ -/* Device-related functions. */ -/*===========================================================================*/ - -static uint8_t _find_address(USBHDriver *host) { - uint8_t addr, i, j; - for (i = 0; i < sizeof_array(host->address_bitmap); i++) { - addr = host->address_bitmap[i]; - for (j = 0; j < 8; j++) { - if ((addr & (1 << j)) == 0) { - //found: - addr = i * 8 + j + 1; - host->address_bitmap[i] |= (1 << j); - return addr; - } - } - } - return 0; -} - -static void _free_address(USBHDriver *host, uint8_t addr) { - uinfof("Free address %d", addr); - host->address_bitmap[addr / 8] &= ~(1 << ((addr - 1) & 7)); -} - -static void _device_initialize(usbh_device_t *dev, usbh_devspeed_t speed) { - dev->address = 0; - dev->speed = speed; - dev->status = USBH_DEVSTATUS_DEFAULT; - dev->langID0 = 0; - dev->keepFullCfgDesc = 0; - _ep0_object_init(dev, 64); -} - -static bool _device_setaddress(usbh_device_t *dev, uint8_t address) { - usbh_urbstatus_t ret = usbhControlRequest(dev, - USBH_STANDARDOUT(USBH_REQTYPE_DEVICE, USBH_REQ_SET_ADDRESS, address, 0), - 0, - 0); - if (ret != USBH_URBSTATUS_OK) - return HAL_FAILED; - - dev->address = address; - return HAL_SUCCESS; -} - -static inline bool _device_read_basic_cfgdesc(usbh_device_t *dev, uint8_t bConfiguration) { - /* get configuration descriptor */ - return usbhStdReqGetConfigurationDescriptor(dev, bConfiguration, - sizeof(dev->basicConfigDesc), (uint8_t *)&dev->basicConfigDesc); -} - -static void _device_read_full_cfgdesc(usbh_device_t *dev, uint8_t bConfiguration) { - _check_dev(dev); - - uint8_t i; - - if (dev->fullConfigurationDescriptor != NULL) { - chHeapFree(dev->fullConfigurationDescriptor); - } - - dev->fullConfigurationDescriptor = - (uint8_t *)chHeapAlloc(0, dev->basicConfigDesc.wTotalLength); - - if (!dev->fullConfigurationDescriptor) - return; - - for (i = 0; i < 3; i++) { - if (usbhStdReqGetConfigurationDescriptor(dev, bConfiguration, - dev->basicConfigDesc.wTotalLength, - dev->fullConfigurationDescriptor) == HAL_SUCCESS) { - return; - } - osalThreadSleepMilliseconds(200); - } - - /* error */ - chHeapFree(dev->fullConfigurationDescriptor); - dev->fullConfigurationDescriptor = NULL; -} - -static void _device_free_full_cfgdesc(usbh_device_t *dev) { - osalDbgCheck(dev); - if (dev->fullConfigurationDescriptor != NULL) { - chHeapFree(dev->fullConfigurationDescriptor); - dev->fullConfigurationDescriptor = NULL; - } -} - - -#define USBH_SET_CONFIGURATION(type, value, index) \ - USBH_STANDARDOUT(type, \ - USBH_REQ_SET_CONFIGURATION, \ - value, \ - index) \ - -#define USBH_SETDEVICECONFIGURATION(index) \ - USBH_SET_CONFIGURATION(USBH_REQTYPE_DEVICE, index, 0) - - -static bool _device_set_configuration(usbh_device_t *dev, uint8_t configuration) { - usbh_urbstatus_t ret = usbhControlRequest(dev, - USBH_SETDEVICECONFIGURATION(configuration), - 0, - 0); - if (ret != USBH_URBSTATUS_OK) - return HAL_FAILED; - return HAL_SUCCESS; -} - -static bool _device_configure(usbh_device_t *dev, uint8_t bConfiguration) { - uint8_t i; - - uinfof("Reading basic configuration descriptor %d", bConfiguration); - for (i = 0; i < 3; i++) { - if (!_device_read_basic_cfgdesc(dev, bConfiguration)) - break; - } - - if (i == 3) { - uerrf("Could not read basic configuration descriptor %d; " - "won't configure device", bConfiguration); - return HAL_FAILED; - } - - uinfof("Selecting configuration %d", bConfiguration); - for (i = 0; i < 3; i++) { - if (!_device_set_configuration(dev, dev->basicConfigDesc.bConfigurationValue)) { - /* TODO: check if correctly configured using GET_CONFIGURATION */ - dev->status = USBH_DEVSTATUS_CONFIGURED; - dev->bConfiguration = bConfiguration; - - uinfo("Device configured."); - return HAL_SUCCESS; - } - } - - return HAL_FAILED; -} - -static bool _device_enumerate(usbh_device_t *dev) { - - uinfo("Enumerate."); - uinfo("Get first 8 bytes of device descriptor"); - - /* get first 8 bytes of device descriptor */ - if (usbhStdReqGetDeviceDescriptor(dev, 8, (uint8_t *)&dev->devDesc)) { - uerr("Error"); - return HAL_FAILED; - } - - uinfof("Configure bMaxPacketSize0 = %d", dev->devDesc.bMaxPacketSize0); - /* configure EP0 wMaxPacketSize */ - usbhEPClose(&dev->ctrl); - _ep0_object_init(dev, dev->devDesc.bMaxPacketSize0); - usbhEPOpen(&dev->ctrl); - - uint8_t addr = _find_address(dev->host); - if (addr == 0) { - uerr("No free addresses found"); - return HAL_FAILED; - } - - /* set device address */ - uinfof("Set device address: %d", addr); - if (_device_setaddress(dev, addr)) { - uerr("Error"); - _free_address(dev->host, addr); - return HAL_FAILED; - } - - /* update EP because of the address change */ - usbhEPClose(&dev->ctrl); - _ep0_object_init(dev, dev->devDesc.bMaxPacketSize0); - usbhEPOpen(&dev->ctrl); - - uinfof("Wait stabilization..."); - osalThreadSleepMilliseconds(HAL_USBH_DEVICE_ADDRESS_STABILIZATION); - - /* address is set */ - dev->status = USBH_DEVSTATUS_ADDRESS; - - uinfof("Get full device desc"); - /* get full device descriptor */ - if (usbhStdReqGetDeviceDescriptor(dev, sizeof(dev->devDesc), - (uint8_t *)&dev->devDesc)) { - uerr("Error"); - _device_setaddress(dev, 0); - _free_address(dev->host, addr); - return HAL_FAILED; - } - - uinfof("Enumeration finished."); - return HAL_SUCCESS; -} - -#if USBH_DEBUG_ENABLE && USBH_DEBUG_ENABLE_INFO -void usbhDevicePrintInfo(usbh_device_t *dev) { - USBH_DEFINE_BUFFER(char, str[64]); - usbh_device_descriptor_t *const desc = &dev->devDesc; - - uinfo("----- Device info -----"); - uinfo("Device descriptor:"); - uinfof("\tUSBSpec=%04x, #configurations=%d, langID0=%04x", - desc->bcdUSB, - desc->bNumConfigurations, - dev->langID0); - - uinfof("\tClass=%02x, Subclass=%02x, Protocol=%02x", - desc->bDeviceClass, - desc->bDeviceSubClass, - desc->bDeviceProtocol); - - uinfof("\tVID=%04x, PID=%04x, Release=%04x", - desc->idVendor, - desc->idProduct, - desc->bcdDevice); - - if (dev->langID0) { - usbhDeviceReadString(dev, str, sizeof(str), desc->iManufacturer, dev->langID0); - uinfof("\tManufacturer: %s", str); - usbhDeviceReadString(dev, str, sizeof(str), desc->iProduct, dev->langID0); - uinfof("\tProduct: %s", str); - usbhDeviceReadString(dev, str, sizeof(str), desc->iSerialNumber, dev->langID0); - uinfof("\tSerial Number: %s", str); - } - - if (dev->status == USBH_DEVSTATUS_CONFIGURED) { - uinfo("Configuration descriptor (partial):"); - usbh_config_descriptor_t *const cfg = &dev->basicConfigDesc; - uinfof("\tbConfigurationValue=%d, Length=%d, #interfaces=%d", - cfg->bConfigurationValue, - cfg->wTotalLength, - cfg->bNumInterfaces); - - uinfof("\tCurrent=%dmA", cfg->bMaxPower * 2); - uinfof("\tSelfPowered=%d, RemoteWakeup=%d", - cfg->bmAttributes & 0x40 ? 1 : 0, - cfg->bmAttributes & 0x20 ? 1 : 0); - if (dev->langID0) { - usbhDeviceReadString(dev, str, sizeof(str), cfg->iConfiguration, dev->langID0); - uinfof("\tName: %s", str); - } - } - - uinfo("----- End Device info -----"); - -} - -void usbhDevicePrintConfiguration(const uint8_t *descriptor, uint16_t rem) { - generic_iterator_t iep, icfg, ics; - if_iterator_t iif; - - uinfo("----- Configuration info -----"); - uinfo("Configuration descriptor:"); - cfg_iter_init(&icfg, descriptor, rem); - const usbh_config_descriptor_t *const cfgdesc = cfg_get(&icfg); - uinfof("Configuration %d, #IFs=%d", cfgdesc->bConfigurationValue, cfgdesc->bNumInterfaces); - - for (if_iter_init(&iif, &icfg); iif.valid; if_iter_next(&iif)) { - const usbh_interface_descriptor_t *const ifdesc = if_get(&iif); - - uinfof(" Interface %d, alt=%d, #EPs=%d, " - "Class=%02x, Subclass=%02x, Protocol=%02x", - ifdesc->bInterfaceNumber, ifdesc->bAlternateSetting, ifdesc->bNumEndpoints, - ifdesc->bInterfaceClass, ifdesc->bInterfaceSubClass, ifdesc->bInterfaceProtocol); - - for (cs_iter_init(&ics, (generic_iterator_t *)&iif); ics.valid; cs_iter_next(&ics)) { - uinfof(" Class-Specific descriptor, Length=%d, Type=%02x", - ics.curr[0], ics.curr[1]); - } - - for (ep_iter_init(&iep, &iif); iep.valid; ep_iter_next(&iep)) { - const usbh_endpoint_descriptor_t *const epdesc = ep_get(&iep); - - uinfof(" Endpoint descriptor, Address=%02x, Type=%d, MaxPacket=%d, Interval=%d", - epdesc->bEndpointAddress, - epdesc->bmAttributes & 3, - epdesc->wMaxPacketSize, - epdesc->bInterval); - - for (cs_iter_init(&ics, &iep); ics.valid; cs_iter_next(&ics)) { - uinfof(" Class-Specific descriptor, Length=%d, Type=%02x", - ics.curr[0], ics.curr[1]); - } - } - } - uinfo("----- End Configuration info -----"); -} -#endif - -bool usbhDeviceReadString(usbh_device_t *dev, char *dest, uint8_t size, - uint8_t index, uint16_t langID) { - - usbh_string_descriptor_t *const desc = (usbh_string_descriptor_t *)dest; - osalDbgAssert(size >= 2, "wrong size"); - - *dest = 0; - if (index == 0) - return HAL_SUCCESS; - if (usbhStdReqGetStringDescriptor(dev, index, langID, size, (uint8_t *)dest)) - return HAL_FAILED; - if (desc->bLength & 1) - return HAL_FAILED; - if (desc->bLength <= 2) - return HAL_SUCCESS; - - uint8_t nchars = desc->bLength / 2; /* including the trailing 0 */ - if (size < nchars) - nchars = size; - - char *src = (char *)&desc->wData[0]; - while (--nchars) { - *dest++ = *src; - src += 2; - } - *dest = 0; - return HAL_SUCCESS; -} - - - - -/*===========================================================================*/ -/* Port processing functions. */ -/*===========================================================================*/ - -static void _port_connected(usbh_port_t *port); - -static void _port_reset(usbh_port_t *port) { - usbhhubControlRequest(port->device.host, -#if HAL_USBH_USE_HUB - port->hub, -#endif - USBH_REQTYPE_OUT | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER, - USBH_REQ_SET_FEATURE, - USBH_PORT_FEAT_RESET, - port->number, - 0, - 0); -} - -static void _port_update_status(usbh_port_t *port) { - uint32_t stat; - if (usbhhubControlRequest(port->device.host, -#if HAL_USBH_USE_HUB - port->hub, -#endif - USBH_REQTYPE_IN | USBH_REQTYPE_CLASS | USBH_REQTYPE_OTHER, - USBH_REQ_GET_STATUS, - 0, - port->number, - 4, - (uint8_t *)&stat) != USBH_URBSTATUS_OK) { - return; - } - port->status = stat & 0xffff; - port->c_status |= stat >> 16; -} - -static void _port_process_status_change(usbh_port_t *port) { - - _port_update_status(port); - - if (port->c_status & USBH_PORTSTATUS_C_CONNECTION) { - /* port connected status changed */ - port->c_status &= ~USBH_PORTSTATUS_C_CONNECTION; - usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_CONNECTION); - if ((port->status & (USBH_PORTSTATUS_CONNECTION | USBH_PORTSTATUS_ENABLE)) - == USBH_PORTSTATUS_CONNECTION) { - if (port->device.status != USBH_DEVSTATUS_DISCONNECTED) { - _usbh_port_disconnected(port); - } - - /* connected, disabled */ - _port_connected(port); - } else { - /* disconnected */ - _usbh_port_disconnected(port); - } - } - - if (port->c_status & USBH_PORTSTATUS_C_RESET) { - port->c_status &= ~USBH_PORTSTATUS_C_RESET; - usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_RESET); - } - - if (port->c_status & USBH_PORTSTATUS_C_ENABLE) { - port->c_status &= ~USBH_PORTSTATUS_C_ENABLE; - usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_ENABLE); - } - - if (port->c_status & USBH_PORTSTATUS_C_OVERCURRENT) { - port->c_status &= ~USBH_PORTSTATUS_C_OVERCURRENT; - usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_OVERCURRENT); - } - - if (port->c_status & USBH_PORTSTATUS_C_SUSPEND) { - port->c_status &= ~USBH_PORTSTATUS_C_SUSPEND; - usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_SUSPEND); - } - -} - - -static void _port_connected(usbh_port_t *port) { - /* connected */ - - systime_t start; - uint8_t i; - uint8_t retries; - usbh_devspeed_t speed; - USBH_DEFINE_BUFFER(usbh_string_descriptor_t, strdesc); - - uinfof("Port %d connected, wait debounce...", port->number); - - port->device.status = USBH_DEVSTATUS_ATTACHED; - - /* wait for attach de-bounce */ - osalThreadSleepMilliseconds(HAL_USBH_PORT_DEBOUNCE_TIME); - - /* check disconnection */ - _port_update_status(port); - if (port->c_status & USBH_PORTSTATUS_C_CONNECTION) { - /* connection state changed; abort */ - goto abort; - } - - port->device.status = USBH_DEVSTATUS_CONNECTED; - retries = 3; - -reset: - for (i = 0; i < 3; i++) { - uinfo("Try reset..."); - port->c_status &= ~(USBH_PORTSTATUS_C_RESET | USBH_PORTSTATUS_C_ENABLE); - _port_reset(port); - osalThreadSleepMilliseconds(20); /* give it some time to reset (min. 10ms) */ - start = osalOsGetSystemTimeX(); - while (TRUE) { - _port_update_status(port); - - /* check for disconnection */ - if (port->c_status & USBH_PORTSTATUS_C_CONNECTION) - goto abort; - - /* check for reset completion */ - if (port->c_status & USBH_PORTSTATUS_C_RESET) { - port->c_status &= ~USBH_PORTSTATUS_C_RESET; - usbhhubClearFeaturePort(port, USBH_PORT_FEAT_C_RESET); - - if ((port->status & (USBH_PORTSTATUS_ENABLE | USBH_PORTSTATUS_CONNECTION)) - == (USBH_PORTSTATUS_ENABLE | USBH_PORTSTATUS_CONNECTION)) { - goto reset_success; - } - } - - /* check for timeout */ - if (osalOsGetSystemTimeX() - start > HAL_USBH_PORT_RESET_TIMEOUT) break; - } - } - - /* reset procedure failed; abort */ - goto abort; - -reset_success: - - uinfo("Reset OK, recovery..."); - - /* reset recovery */ - osalThreadSleepMilliseconds(100); - - /* initialize object */ - if (port->status & USBH_PORTSTATUS_LOW_SPEED) { - speed = USBH_DEVSPEED_LOW; - } else if (port->status & USBH_PORTSTATUS_HIGH_SPEED) { - speed = USBH_DEVSPEED_HIGH; - } else { - speed = USBH_DEVSPEED_FULL; - } - _device_initialize(&port->device, speed); - usbhEPOpen(&port->device.ctrl); - - /* device with default address (0), try enumeration */ - if (_device_enumerate(&port->device)) { - /* enumeration failed */ - usbhEPClose(&port->device.ctrl); - - if (!--retries) - goto abort; - - /* retry reset & enumeration */ - goto reset; - } - - /* load the default language ID */ - uinfo("Loading langID0..."); - if (!usbhStdReqGetStringDescriptor(&port->device, 0, 0, - USBH_DT_STRING_SIZE, (uint8_t *)&strdesc) - && (strdesc.bLength >= 4) - && !usbhStdReqGetStringDescriptor(&port->device, 0, 0, - 4, (uint8_t *)&strdesc)) { - - port->device.langID0 = strdesc.wData[0]; - uinfof("langID0=%04x", port->device.langID0); - } - - /* check if the device has only one configuration */ - if (port->device.devDesc.bNumConfigurations == 1) { - uinfo("Device has only one configuration"); - _device_configure(&port->device, 0); - } - - _classdriver_process_device(&port->device); - return; - -abort: - uerr("Abort"); - port->device.status = USBH_DEVSTATUS_DISCONNECTED; -} - -void _usbh_port_disconnected(usbh_port_t *port) { - if (port->device.status == USBH_DEVSTATUS_DISCONNECTED) - return; - - uinfo("Port disconnected"); - - /* unload drivers */ - while (port->device.drivers) { - usbh_baseclassdriver_t *drv = port->device.drivers; - - /* unload */ - uinfof("Unload driver %s", drv->info->name); - drv->info->vmt->unload(drv); - - /* unlink */ - drv->dev = 0; - port->device.drivers = drv->next; - } - - /* close control endpoint */ - osalSysLock(); - usbhEPCloseS(&port->device.ctrl); - osalSysUnlock(); - - /* free address */ - if (port->device.address) - _free_address(port->device.host, port->device.address); - - _device_free_full_cfgdesc(&port->device); - - port->device.status = USBH_DEVSTATUS_DISCONNECTED; -} - - - -/*===========================================================================*/ -/* Hub processing functions. */ -/*===========================================================================*/ - -#if HAL_USBH_USE_HUB -static void _hub_update_status(USBHDriver *host, USBHHubDriver *hub) { - uint32_t stat; - if (usbhhubControlRequest(host, - hub, - USBH_REQTYPE_IN | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE, - USBH_REQ_GET_STATUS, - 0, - 0, - 4, - (uint8_t *)&stat) != USBH_URBSTATUS_OK) { - return; - } - if (hub) { - hub->status = stat & 0xffff; - hub->c_status |= stat >> 16; - } -} - -static void _hub_process_status_change(USBHDriver *host, USBHHubDriver *hub) { - uinfo("Hub status change. GET_STATUS."); - _hub_update_status(host, hub); - - if (hub->c_status & USBH_HUBSTATUS_C_HUB_LOCAL_POWER) { - hub->c_status &= ~USBH_HUBSTATUS_C_HUB_LOCAL_POWER; - uinfo("Clear USBH_HUB_FEAT_C_HUB_LOCAL_POWER"); - usbhhubClearFeatureHub(host, hub, USBH_HUB_FEAT_C_HUB_LOCAL_POWER); - } - - if (hub->c_status & USBH_HUBSTATUS_C_HUB_OVER_CURRENT) { - hub->c_status &= ~USBH_HUBSTATUS_C_HUB_OVER_CURRENT; - uinfo("Clear USBH_HUB_FEAT_C_HUB_OVER_CURRENT"); - usbhhubClearFeatureHub(host, hub, USBH_HUB_FEAT_C_HUB_OVER_CURRENT); - } -} - -static uint32_t _hub_get_status_change_bitmap(USBHDriver *host, USBHHubDriver *hub) { - if (hub != NULL) { - osalSysLock(); - uint32_t ret = hub->statuschange; - hub->statuschange = 0; - osalOsRescheduleS(); - osalSysUnlock(); - return ret; - } - return usbh_lld_roothub_get_statuschange_bitmap(host); -} - -#else -//TODO: replace the functions above -#endif - -#if HAL_USBH_USE_HUB -static void _hub_process(USBHDriver *host, USBHHubDriver *hub) { - uint32_t bitmap = _hub_get_status_change_bitmap(host, hub); - if (!bitmap) - return; - - if (bitmap & 1) { - _hub_process_status_change(host, hub); - bitmap &= ~1; - } - - usbh_port_t *port = (hub == NULL) ? &host->rootport : hub->ports; - uint8_t i; - for (i = 1; i < 32; i++) { - if (!bitmap || !port) - break; - if (bitmap & (1 << i)) { - bitmap &= ~(1 << i); - _port_process_status_change(port); - } - port = port->next; - } - -} -#else -static void _hub_process(USBHDriver *host) { - uint32_t bitmap = usbh_lld_roothub_get_statuschange_bitmap(host); - -#if 0 //TODO: complete _hub_process_status_change for root hub - if (bitmap & 1) { - _hub_process_status_change(host, hub); - bitmap &= ~1; - } -#endif - - if (!bitmap) - return; - - _port_process_status_change(&host->rootport); -} -#endif - -/*===========================================================================*/ -/* Main processing loop (enumeration, loading/unloading drivers, etc). */ -/*===========================================================================*/ -void usbhMainLoop(USBHDriver *usbh) { - - if (usbh->status == USBH_STATUS_STOPPED) - return; - -#if HAL_USBH_USE_HUB - /* process root hub */ - _hub_process(usbh, NULL); - - /* process connected hubs */ - USBHHubDriver *hub; - list_for_each_entry(hub, USBHHubDriver, &usbh->hubs, node) { - _hub_process(usbh, hub); - } -#else - /* process root hub */ - _hub_process(usbh); -#endif -} - - -/*===========================================================================*/ -/* IAD class driver. */ -/*===========================================================================*/ -#if HAL_USBH_USE_IAD -static usbh_baseclassdriver_t *iad_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); -static void iad_unload(usbh_baseclassdriver_t *drv); -static const usbh_classdriver_vmt_t usbhiadClassDriverVMT = { - iad_load, - iad_unload -}; -static const usbh_classdriverinfo_t usbhiadClassDriverInfo = { - 0xef, 0x02, 0x01, "IAD", &usbhiadClassDriverVMT -}; - -static usbh_baseclassdriver_t *iad_load(usbh_device_t *dev, - const uint8_t *descriptor, uint16_t rem) { - (void)rem; - - if (descriptor[1] != USBH_DT_DEVICE) - return 0; - - uinfo("Load a driver for each IF collection."); - - generic_iterator_t icfg; - if_iterator_t iif; - const usbh_ia_descriptor_t *last_iad = 0; - - cfg_iter_init(&icfg, dev->fullConfigurationDescriptor, - dev->basicConfigDesc.wTotalLength); - if (!icfg.valid) { - uerr("Invalid configuration descriptor."); - return 0; - } - - for (if_iter_init(&iif, &icfg); iif.valid; if_iter_next(&iif)) { - if (iif.iad && (iif.iad != last_iad)) { - last_iad = iif.iad; - if (_classdriver_load(dev, iif.iad->bFunctionClass, - iif.iad->bFunctionSubClass, - iif.iad->bFunctionProtocol, - (uint8_t *)iif.iad, - (uint8_t *)iif.curr - (uint8_t *)iif.iad + iif.rem) != HAL_SUCCESS) { - uwarnf("No drivers found for IF collection #%d:%d", - iif.iad->bFirstInterface, - iif.iad->bFirstInterface + iif.iad->bInterfaceCount - 1); - } - } - } - - return 0; -} - -static void iad_unload(usbh_baseclassdriver_t *drv) { - (void)drv; -} -#endif - - -/*===========================================================================*/ -/* Class driver loader. */ -/*===========================================================================*/ - -static const usbh_classdriverinfo_t *usbh_classdrivers_lookup[] = { -#if HAL_USBH_USE_FTDI - &usbhftdiClassDriverInfo, -#endif -#if HAL_USBH_USE_IAD - &usbhiadClassDriverInfo, -#endif -#if HAL_USBH_USE_UVC - &usbhuvcClassDriverInfo, -#endif -#if HAL_USBH_USE_MSD - &usbhmsdClassDriverInfo, -#endif -#if HAL_USBH_USE_HUB - &usbhhubClassDriverInfo -#endif -}; - -static bool _classdriver_load(usbh_device_t *dev, uint8_t class, - uint8_t subclass, uint8_t protocol, uint8_t *descbuff, uint16_t rem) { - uint8_t i; - usbh_baseclassdriver_t *drv = NULL; - for (i = 0; i < sizeof_array(usbh_classdrivers_lookup); i++) { - const usbh_classdriverinfo_t *const info = usbh_classdrivers_lookup[i]; - if (class == 0xff) { - /* vendor specific */ - if (info->class == 0xff) { - uinfof("Try load vendor-specific driver %s", info->name); - drv = info->vmt->load(dev, descbuff, rem); - if (drv != NULL) - goto success; - } - } else if ((info->class < 0) || ((info->class == class) - && ((info->subclass < 0) || ((info->subclass == subclass) - && ((info->protocol < 0) || (info->protocol == protocol)))))) { - uinfof("Try load driver %s", info->name); - drv = info->vmt->load(dev, descbuff, rem); - -#if HAL_USBH_USE_IAD - /* special case: */ - if (info == &usbhiadClassDriverInfo) - return HAL_SUCCESS; -#endif - - if (drv != NULL) - goto success; - } - } - return HAL_FAILED; - -success: - /* Link this driver to the device */ - drv->next = dev->drivers; - dev->drivers = drv; - drv->dev = dev; - return HAL_SUCCESS; -} - -static void _classdriver_process_device(usbh_device_t *dev) { - uinfo("New device found."); - const usbh_device_descriptor_t *const devdesc = &dev->devDesc; - - usbhDevicePrintInfo(dev); - - /* TODO: Support multiple configurations - * - * Windows doesn't support them, so it's unlikely that any commercial USB device - * will have multiple configurations. - */ - if (dev->status != USBH_DEVSTATUS_CONFIGURED) { - uwarn("Multiple configurations not supported, selecting configuration #0"); - if (_device_configure(dev, 0) != HAL_SUCCESS) { - uerr("Couldn't configure device; abort."); - return; - } - } - - _device_read_full_cfgdesc(dev, dev->bConfiguration); - if (dev->fullConfigurationDescriptor == NULL) { - uerr("Couldn't read full configuration descriptor; abort."); - return; - } - - usbhDevicePrintConfiguration(dev->fullConfigurationDescriptor, - dev->basicConfigDesc.wTotalLength); - - if (devdesc->bDeviceClass == 0) { - /* each interface defines its own device class/subclass/protocol */ - uinfo("Load a driver for each IF."); - - generic_iterator_t icfg; - if_iterator_t iif; - uint8_t last_if = 0xff; - - cfg_iter_init(&icfg, dev->fullConfigurationDescriptor, - dev->basicConfigDesc.wTotalLength); - if (!icfg.valid) { - uerr("Invalid configuration descriptor."); - goto exit; - } - - for (if_iter_init(&iif, &icfg); iif.valid; if_iter_next(&iif)) { - const usbh_interface_descriptor_t *const ifdesc = if_get(&iif); - if (ifdesc->bInterfaceNumber != last_if) { - last_if = ifdesc->bInterfaceNumber; - if (_classdriver_load(dev, ifdesc->bInterfaceClass, - ifdesc->bInterfaceSubClass, - ifdesc->bInterfaceProtocol, - (uint8_t *)ifdesc, iif.rem) != HAL_SUCCESS) { - uwarnf("No drivers found for IF #%d", ifdesc->bInterfaceNumber); - } - } - } - - } else { - if (_classdriver_load(dev, devdesc->bDeviceClass, - devdesc->bDeviceSubClass, - devdesc->bDeviceProtocol, - (uint8_t *)devdesc, USBH_DT_DEVICE_SIZE) != HAL_SUCCESS) { - uwarn("No drivers found."); - } - } - -exit: - if (dev->keepFullCfgDesc == 0) { - _device_free_full_cfgdesc(dev); - } -} - - -#endif - diff --git a/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_debug.c b/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_debug.c deleted file mode 100644 index 9f17189..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_debug.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio - Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail) - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#include "hal.h" - -#if HAL_USE_USBH - -#include "ch.h" -#include "usbh/debug.h" -#include -#include "chprintf.h" - -#if USBH_DEBUG_ENABLE - -#define MAX_FILLER 11 -#define FLOAT_PRECISION 9 -#define MPRINTF_USE_FLOAT 0 - -static char *long_to_string_with_divisor(char *p, long num, unsigned radix, long divisor) -{ - int i; - char *q; - long l, ll; - - l = num; - if (divisor == 0) { - ll = num; - } else { - ll = divisor; - } - - q = p + MAX_FILLER; - do { - i = (int)(l % radix); - i += '0'; - if (i > '9') { - i += 'A' - '0' - 10; - } - *--q = i; - l /= radix; - } while ((ll /= radix) != 0); - - i = (int)(p + MAX_FILLER - q); - do { - *p++ = *q++; - } while (--i); - - return p; -} - -static char *ltoa(char *p, long num, unsigned radix) { - - return long_to_string_with_divisor(p, num, radix, 0); -} - -#if MPRINTF_USE_FLOAT -static const long _pow10[FLOAT_PRECISION] = {10, 100, 1000, 10000, 100000, 1000000, - 10000000, 100000000, 1000000000}; -static const double m10[FLOAT_PRECISION] = {5.0/100, 5.0/1000, 5.0/10000, 5.0/100000, 5.0/1000000, - 5.0/10000000, 5.0/100000000, 5.0/1000000000, 5.0/10000000000}; - -static char *ftoa(char *p, double num, unsigned long precision, bool dot) { - long l; - char *q; - double r; - - - if (precision == 0) { - l = (long)(num + 0.5); - return long_to_string_with_divisor(p, l, 10, 0); - } else { - if (precision > FLOAT_PRECISION) precision = FLOAT_PRECISION; - r = m10[precision - 1]; - precision = _pow10[precision - 1]; - - l = (long)num; - p = long_to_string_with_divisor(p, l, 10, 0); - if (dot) *p++ = '.'; - l = (long)((num - l + r) * precision); - q = long_to_string_with_divisor(p, l, 10, precision / 10) - 1; - - while (q > p) { - if (*q != '0') { - break; - } - --q; - } - return ++q; - } - - - - -} -#endif - -static inline void _put(char c) { - input_queue_t *iqp = &USBH_DEBUG_USBHD.iq; - - if (chIQIsFullI(iqp)) - return; - - iqp->q_counter++; - *iqp->q_wrptr++ = c; - if (iqp->q_wrptr >= iqp->q_top) - iqp->q_wrptr = iqp->q_buffer; - -} - -int _dbg_printf(const char *fmt, va_list ap) { - char *p, *s, c, filler; - int i, precision, width; - int n = 0; - bool is_long, left_align, sign; - long l; -#if MPRINTF_USE_FLOAT - double f; - char tmpbuf[2*MAX_FILLER + 1]; -#else - char tmpbuf[MAX_FILLER + 1]; -#endif - - for (;;) { - - //agarrar nuevo caracter de formato - c = *fmt++; - - //chequeo eos - if (c == 0) return n; - - //copio los caracteres comunes - if (c != '%') { - _put(c); - n++; - continue; - } - - //encontré un '%' - p = tmpbuf; - s = tmpbuf; - - //left align - left_align = FALSE; - if (*fmt == '-') { - fmt++; - left_align = TRUE; - } - - sign = FALSE; - if (*fmt == '+') { - fmt++; - sign = TRUE; - } - - //filler - filler = ' '; - if (*fmt == '0') { - fmt++; - filler = '0'; - } - - //width - width = 0; - while (TRUE) { - c = *fmt++; - if (c >= '0' && c <= '9') - c -= '0'; - else if (c == '*') - c = va_arg(ap, int); - else - break; - width = width * 10 + c; - } - - //precision - precision = 0; - if (c == '.') { - - if (*fmt == 'n') { - fmt++; - - } - while (TRUE) { - c = *fmt++; - if (c >= '0' && c <= '9') - c -= '0'; - else if (c == '*') - c = va_arg(ap, int); - else - break; - precision = precision * 10 + c; - } - } - - //long modifier - if (c == 'l' || c == 'L') { - is_long = TRUE; - if (*fmt) - c = *fmt++; - } - else - is_long = (c >= 'A') && (c <= 'Z'); - - /* Command decoding.*/ - switch (c) { - //char - case 'c': - filler = ' '; - *p++ = va_arg(ap, int); - break; - - //string - case 's': - filler = ' '; - if ((s = va_arg(ap, char *)) == 0) - s = (char *)"(null)"; - if (precision == 0) - precision = 32767; - - //strlen con límite hasta precision - for (p = s; *p && (--precision >= 0); p++) - ; - break; - - - - case 'D': - case 'd': - case 'I': - case 'i': - if (is_long) - l = va_arg(ap, long); - else - l = va_arg(ap, int); - if (l < 0) { - *p++ = '-'; - l = -l; - sign = TRUE; - } else if (sign) { - *p++ = '+'; - } - p = ltoa(p, l, 10); - break; - -#if MPRINTF_USE_FLOAT - case 'f': - f = va_arg(ap, double); - if (f < 0) { - *p++ = '-'; - f = -f; - sign = TRUE; - } else if (sign) { - *p++ = '+'; - } - if (prec == FALSE) precision = 6; - p = ftoa(p, f, precision, dot); - break; -#endif - - - case 'X': - case 'x': - c = 16; - goto unsigned_common; - case 'U': - case 'u': - c = 10; - goto unsigned_common; - case 'O': - case 'o': - c = 8; - -unsigned_common: - if (is_long) - l = va_arg(ap, unsigned long); - else - l = va_arg(ap, unsigned int); - p = ltoa(p, l, c); - break; - - //copiar - default: - *p++ = c; - break; - } - - //longitud - i = (int)(p - s); - - //calculo cuántos caracteres de filler debo poner - if ((width -= i) < 0) - width = 0; - - if (left_align == FALSE) - width = -width; - - if (width < 0) { - //alineado a la derecha - - //poner el signo adelante - if (sign && filler == '0') { - _put(*s++); - n++; - i--; - } - - //fill a la izquierda - do { - _put(filler); - n++; - } while (++width != 0); - } - - //copiar los caracteres - while (--i >= 0) { - _put(*s++); - n++; - } - - //fill a la derecha - while (width) { - _put(filler); - n++; - width--; - } - } - - //return n; // can raise 'code is unreachable' warning - -} - -static void _print_hdr(void) -{ - uint32_t hfnum = USBH_DEBUG_USBHD.otg->HFNUM; - uint16_t hfir = USBH_DEBUG_USBHD.otg->HFIR; - - _put(0xff); - _put(0xff); - _put(hfir & 0xff); - _put(hfir >> 8); - _put(hfnum & 0xff); - _put((hfnum >> 8) & 0xff); - _put((hfnum >> 16) & 0xff); - _put((hfnum >> 24) & 0xff); -} - -void usbDbgPrintf(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - syssts_t sts = chSysGetStatusAndLockX(); - _print_hdr(); - _dbg_printf(fmt, ap); - _put(0); - chThdDequeueNextI(&USBH_DEBUG_USBHD.iq.q_waiting, Q_OK); - chSysRestoreStatusX(sts); - va_end(ap); -} - - -void usbDbgPuts(const char *s) -{ - uint32_t buff[2] = { - 0xffff | (USBH_DEBUG_USBHD.otg->HFIR << 16), - USBH_DEBUG_USBHD.otg->HFNUM - }; - uint8_t *p = (uint8_t *)buff; - uint8_t *top = p + 8; - - syssts_t sts = chSysGetStatusAndLockX(); - input_queue_t *iqp = &USBH_DEBUG_USBHD.iq; - int rem = sizeof(USBH_DEBUG_USBHD.dbg_buff) - iqp->q_counter; - while (rem) { - *iqp->q_wrptr++ = *p; - if (iqp->q_wrptr >= iqp->q_top) - iqp->q_wrptr = iqp->q_buffer; - rem--; - if (++p == top) break; - } - while (rem) { - *iqp->q_wrptr++ = *s; - if (iqp->q_wrptr >= iqp->q_top) - iqp->q_wrptr = iqp->q_buffer; - rem--; - if (!*s++) break; - } - iqp->q_counter = sizeof(USBH_DEBUG_USBHD.dbg_buff) - rem; - chThdDequeueNextI(&USBH_DEBUG_USBHD.iq.q_waiting, Q_OK); - chSysRestoreStatusX(sts); -} - -void usbDbgReset(void) { - const char *msg = "\r\n\r\n==== DEBUG OUTPUT RESET ====\r\n"; - - syssts_t sts = chSysGetStatusAndLockX(); - chIQResetI(&USBH_DEBUG_USBHD.iq); - chOQResetI(&USBH_DEBUG_SD.oqueue); - while (*msg) { - *USBH_DEBUG_SD.oqueue.q_wrptr++ = *msg++; - USBH_DEBUG_SD.oqueue.q_counter--; - } - chSysRestoreStatusX(sts); -} - -static int _get(void) { - if (!USBH_DEBUG_USBHD.iq.q_counter) return -1; - USBH_DEBUG_USBHD.iq.q_counter--; - uint8_t b = *USBH_DEBUG_USBHD.iq.q_rdptr++; - if (USBH_DEBUG_USBHD.iq.q_rdptr >= USBH_DEBUG_USBHD.iq.q_top) { - USBH_DEBUG_USBHD.iq.q_rdptr = USBH_DEBUG_USBHD.iq.q_buffer; - } - return b; -} - -void usbDbgSystemHalted(void) { - while (true) { - if (!((bool)((USBH_DEBUG_SD.oqueue.q_wrptr == USBH_DEBUG_SD.oqueue.q_rdptr) && (USBH_DEBUG_SD.oqueue.q_counter != 0U)))) - break; - USBH_DEBUG_SD.oqueue.q_counter++; - while (!(USART1->SR & USART_SR_TXE)); - USART1->DR = *USBH_DEBUG_SD.oqueue.q_rdptr++; - if (USBH_DEBUG_SD.oqueue.q_rdptr >= USBH_DEBUG_SD.oqueue.q_top) { - USBH_DEBUG_SD.oqueue.q_rdptr = USBH_DEBUG_SD.oqueue.q_buffer; - } - } - - int c; - int state = 0; - for (;;) { - c = _get(); if (c < 0) break; - - if (state == 0) { - if (c == 0xff) state = 1; - } else if (state == 1) { - if (c == 0xff) state = 2; - else (state = 0); - } else { - c = _get(); if (c < 0) return; - c = _get(); if (c < 0) return; - c = _get(); if (c < 0) return; - c = _get(); if (c < 0) return; - c = _get(); if (c < 0) return; - - while (true) { - c = _get(); if (c < 0) return; - if (!c) { - while (!(USART1->SR & USART_SR_TXE)); - USART1->DR = '\r'; - while (!(USART1->SR & USART_SR_TXE)); - USART1->DR = '\n'; - state = 0; - break; - } - while (!(USART1->SR & USART_SR_TXE)); - USART1->DR = c; - } - } - } -} - -static void usb_debug_thread(void *p) { - USBHDriver *host = (USBHDriver *)p; - uint8_t state = 0; - - chRegSetThreadName("USBH_DBG"); - while (true) { - msg_t c = chIQGet(&host->iq); - if (c < 0) goto reset; - - if (state == 0) { - if (c == 0xff) state = 1; - } else if (state == 1) { - if (c == 0xff) state = 2; - else (state = 0); - } else { - uint16_t hfir; - uint32_t hfnum; - - hfir = c; - c = chIQGet(&host->iq); if (c < 0) goto reset; - hfir |= c << 8; - - c = chIQGet(&host->iq); if (c < 0) goto reset; - hfnum = c; - c = chIQGet(&host->iq); if (c < 0) goto reset; - hfnum |= c << 8; - c = chIQGet(&host->iq); if (c < 0) goto reset; - hfnum |= c << 16; - c = chIQGet(&host->iq); if (c < 0) goto reset; - hfnum |= c << 24; - - uint32_t f = hfnum & 0xffff; - uint32_t p = 1000 - ((hfnum >> 16) / (hfir / 1000)); - chprintf((BaseSequentialStream *)&USBH_DEBUG_SD, "%05d.%03d ", f, p); - - while (true) { - c = chIQGet(&host->iq); if (c < 0) goto reset; - if (!c) { - sdPut(&USBH_DEBUG_SD, '\r'); - sdPut(&USBH_DEBUG_SD, '\n'); - state = 0; - break; - } - sdPut(&USBH_DEBUG_SD, (uint8_t)c); - } - } - - continue; -reset: - state = 0; - } -} - -void usbDbgInit(USBHDriver *host) { - if (host != &USBH_DEBUG_USBHD) - return; - chIQObjectInit(&USBH_DEBUG_USBHD.iq, USBH_DEBUG_USBHD.dbg_buff, sizeof(USBH_DEBUG_USBHD.dbg_buff), 0, 0); - chThdCreateStatic(USBH_DEBUG_USBHD.waDebug, sizeof(USBH_DEBUG_USBHD.waDebug), NORMALPRIO, usb_debug_thread, &USBH_DEBUG_USBHD); -} -#endif - -#endif diff --git a/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_desciter.c b/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_desciter.c deleted file mode 100644 index 63137d4..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_desciter.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio - Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail) - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#include "hal.h" - -#if HAL_USE_USBH - -#include "usbh/defs.h" -#include "usbh/desciter.h" - -void cfg_iter_init(generic_iterator_t *icfg, const uint8_t *buff, uint16_t rem) { - icfg->valid = 0; - - if ((buff[0] < 2) || (rem < 2) || (rem < buff[0]) - || (buff[0] < USBH_DT_CONFIG_SIZE) - || (buff[1] != USBH_DT_CONFIG)) - return; - - if (rem > ((usbh_config_descriptor_t *)buff)->wTotalLength) { - rem = ((usbh_config_descriptor_t *)buff)->wTotalLength; - } - - icfg->valid = 1; - icfg->rem = rem; - icfg->curr = buff; -} - -void if_iter_next(if_iterator_t *iif) { - const uint8_t *curr = iif->curr; - uint16_t rem = iif->rem; - - iif->valid = 0; - - if ((curr[0] < 2) || (rem < 2) || (rem < curr[0])) - return; - - for (;;) { - rem -= curr[0]; - curr += curr[0]; - - if ((curr[0] < 2) || (rem < 2) || (rem < curr[0])) - return; - - if (curr[1] == USBH_DT_INTERFACE_ASSOCIATION) { - if (curr[0] < USBH_DT_INTERFACE_ASSOCIATION_SIZE) - return; - - iif->iad = (usbh_ia_descriptor_t *)curr; - - } else if (curr[1] == USBH_DT_INTERFACE) { - if (curr[0] < USBH_DT_INTERFACE_SIZE) - return; - - if (iif->iad) { - if ((curr[2] < iif->iad->bFirstInterface) - || (curr[2] >= (iif->iad->bFirstInterface + iif->iad->bInterfaceCount))) - iif->iad = 0; - } - break; - } - } - - iif->valid = 1; - iif->rem = rem; - iif->curr = curr; -} - -void if_iter_init(if_iterator_t *iif, const generic_iterator_t *icfg) { - iif->iad = 0; - iif->curr = icfg->curr; - iif->rem = icfg->rem; - if_iter_next(iif); -} - -void ep_iter_next(generic_iterator_t *iep) { - const uint8_t *curr = iep->curr; - uint16_t rem = iep->rem; - - iep->valid = 0; - - if ((curr[0] < 2) || (rem < 2) || (rem < curr[0])) - return; - - for (;;) { - rem -= curr[0]; - curr += curr[0]; - - if ((curr[0] < 2) || (rem < 2) || (rem < curr[0])) - return; - - if ((curr[1] == USBH_DT_INTERFACE_ASSOCIATION) - || (curr[1] == USBH_DT_INTERFACE) - || (curr[1] == USBH_DT_CONFIG)) { - return; - } else if (curr[1] == USBH_DT_ENDPOINT) { - if (curr[0] < USBH_DT_ENDPOINT_SIZE) - return; - - break; - } - } - - iep->valid = 1; - iep->rem = rem; - iep->curr = curr; -} - -void ep_iter_init(generic_iterator_t *iep, const if_iterator_t *iif) { - iep->curr = iif->curr; - iep->rem = iif->rem; - ep_iter_next(iep); -} - -void cs_iter_next(generic_iterator_t *ics) { - const uint8_t *curr = ics->curr; - uint16_t rem = ics->rem; - - ics->valid = 0; - - if ((curr[0] < 2) || (rem < 2) || (rem < curr[0])) - return; - - //for (;;) { - rem -= curr[0]; - curr += curr[0]; - - if ((curr[0] < 2) || (rem < 2) || (rem < curr[0])) - return; - - if ((curr[1] == USBH_DT_INTERFACE_ASSOCIATION) - || (curr[1] == USBH_DT_INTERFACE) - || (curr[1] == USBH_DT_CONFIG) - || (curr[1] == USBH_DT_ENDPOINT)) { - return; - } - - // break; - //} - - ics->valid = 1; - ics->rem = rem; - ics->curr = curr; -} - -void cs_iter_init(generic_iterator_t *ics, const generic_iterator_t *iter) { - ics->curr = iter->curr; - ics->rem = iter->rem; - cs_iter_next(ics); -} - -#endif diff --git a/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_ftdi.c b/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_ftdi.c deleted file mode 100644 index 4bd7296..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_ftdi.c +++ /dev/null @@ -1,717 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio - Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail) - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#include "hal.h" -#include "hal_usbh.h" - -#if HAL_USBH_USE_FTDI - -#if !HAL_USE_USBH -#error "USBHFTDI needs USBH" -#endif - -#include -#include "usbh/dev/ftdi.h" -#include "usbh/internal.h" - -//#pragma GCC optimize("Og") - - -#if USBHFTDI_DEBUG_ENABLE_TRACE -#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define udbgf(f, ...) do {} while(0) -#define udbg(f, ...) do {} while(0) -#endif - -#if USBHFTDI_DEBUG_ENABLE_INFO -#define uinfof(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define uinfo(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define uinfof(f, ...) do {} while(0) -#define uinfo(f, ...) do {} while(0) -#endif - -#if USBHFTDI_DEBUG_ENABLE_WARNINGS -#define uwarnf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define uwarn(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define uwarnf(f, ...) do {} while(0) -#define uwarn(f, ...) do {} while(0) -#endif - -#if USBHFTDI_DEBUG_ENABLE_ERRORS -#define uerrf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define uerr(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define uerrf(f, ...) do {} while(0) -#define uerr(f, ...) do {} while(0) -#endif - - -/*===========================================================================*/ -/* USB Class driver loader for FTDI */ -/*===========================================================================*/ -USBHFTDIDriver USBHFTDID[HAL_USBHFTDI_MAX_INSTANCES]; - -static usbh_baseclassdriver_t *_ftdi_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); -static void _ftdi_unload(usbh_baseclassdriver_t *drv); - -static const usbh_classdriver_vmt_t class_driver_vmt = { - _ftdi_load, - _ftdi_unload -}; - -const usbh_classdriverinfo_t usbhftdiClassDriverInfo = { - 0xff, 0xff, 0xff, "FTDI", &class_driver_vmt -}; - -static USBHFTDIPortDriver *_find_port(void) { - uint8_t i; - for (i = 0; i < HAL_USBHFTDI_MAX_PORTS; i++) { - if (FTDIPD[i].ftdip == NULL) - return &FTDIPD[i]; - } - return NULL; -} - -static usbh_baseclassdriver_t *_ftdi_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem) { - int i; - USBHFTDIDriver *ftdip; - - if (dev->devDesc.idVendor != 0x0403) { - uerr("FTDI: Unrecognized VID"); - return NULL; - } - - switch (dev->devDesc.idProduct) { - case 0x6001: - case 0x6010: - case 0x6011: - case 0x6014: - case 0x6015: - break; - default: - uerr("FTDI: Unrecognized PID"); - return NULL; - } - - if ((rem < descriptor[0]) || (descriptor[1] != USBH_DT_INTERFACE)) - return NULL; - - const usbh_interface_descriptor_t * const ifdesc = (const usbh_interface_descriptor_t * const)descriptor; - if (ifdesc->bInterfaceNumber != 0) { - uwarn("FTDI: Will allocate driver along with IF #0"); - } - - /* alloc driver */ - for (i = 0; i < HAL_USBHFTDI_MAX_INSTANCES; i++) { - if (USBHFTDID[i].dev == NULL) { - ftdip = &USBHFTDID[i]; - goto alloc_ok; - } - } - - uwarn("FTDI: Can't alloc driver"); - - /* can't alloc */ - return NULL; - -alloc_ok: - /* initialize the driver's variables */ - ftdip->ports = 0; - switch (dev->devDesc.bcdDevice) { - case 0x200: //AM - uinfo("FTDI: Type A chip"); - ftdip->type = USBHFTDI_TYPE_A; - break; - case 0x400: //BM - case 0x500: //2232C - case 0x600: //R - case 0x1000: //230X - uinfo("FTDI: Type B chip"); - ftdip->type = USBHFTDI_TYPE_B; - break; - case 0x700: //2232H; - case 0x800: //4232H; - case 0x900: //232H; - uinfo("FTDI: Type H chip"); - ftdip->type = USBHFTDI_TYPE_H; - default: - uerr("FTDI: Unrecognized chip type"); - return NULL; - } - usbhEPSetName(&dev->ctrl, "FTD[CTRL]"); - - /* parse the configuration descriptor */ - generic_iterator_t iep, icfg; - if_iterator_t iif; - cfg_iter_init(&icfg, dev->fullConfigurationDescriptor, dev->basicConfigDesc.wTotalLength); - for (if_iter_init(&iif, &icfg); iif.valid; if_iter_next(&iif)) { - const usbh_interface_descriptor_t *const ifdesc = if_get(&iif); - uinfof("FTDI: Interface #%d", ifdesc->bInterfaceNumber); - - USBHFTDIPortDriver *const prt = _find_port(); - if (prt == NULL) { - uwarn("\tCan't alloc port for this interface"); - break; - } - - prt->ifnum = ifdesc->bInterfaceNumber; - prt->epin.status = USBH_EPSTATUS_UNINITIALIZED; - prt->epout.status = USBH_EPSTATUS_UNINITIALIZED; - - for (ep_iter_init(&iep, &iif); iep.valid; ep_iter_next(&iep)) { - const usbh_endpoint_descriptor_t *const epdesc = ep_get(&iep); - if ((epdesc->bEndpointAddress & 0x80) && (epdesc->bmAttributes == USBH_EPTYPE_BULK)) { - uinfof("BULK IN endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress); - usbhEPObjectInit(&prt->epin, dev, epdesc); - usbhEPSetName(&prt->epin, "FTD[BIN ]"); - } else if (((epdesc->bEndpointAddress & 0x80) == 0) - && (epdesc->bmAttributes == USBH_EPTYPE_BULK)) { - uinfof("BULK OUT endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress); - usbhEPObjectInit(&prt->epout, dev, epdesc); - usbhEPSetName(&prt->epout, "FTD[BOUT]"); - } else { - uinfof("unsupported endpoint found: bEndpointAddress=%02x, bmAttributes=%02x", - epdesc->bEndpointAddress, epdesc->bmAttributes); - } - } - - if ((prt->epin.status != USBH_EPSTATUS_CLOSED) - || (prt->epout.status != USBH_EPSTATUS_CLOSED)) { - uwarn("\tCouldn't find endpoints; can't alloc port for this interface"); - continue; - } - - /* link the new block driver to the list */ - prt->next = ftdip->ports; - ftdip->ports = prt; - prt->ftdip = ftdip; - - prt->state = USBHFTDIP_STATE_ACTIVE; - } - - return (usbh_baseclassdriver_t *)ftdip; - -} - -static void _stop(USBHFTDIPortDriver *ftdipp); -static void _ftdi_unload(usbh_baseclassdriver_t *drv) { - osalDbgCheck(drv != NULL); - USBHFTDIDriver *const ftdip = (USBHFTDIDriver *)drv; - USBHFTDIPortDriver *ftdipp = ftdip->ports; - - osalMutexLock(&ftdip->mtx); - while (ftdipp) { - _stop(ftdipp); - ftdipp = ftdipp->next; - } - - ftdipp = ftdip->ports; - osalSysLock(); - while (ftdipp) { - USBHFTDIPortDriver *next = ftdipp->next; - usbhftdipObjectInit(ftdipp); - ftdipp = next; - } - osalSysUnlock(); - osalMutexUnlock(&ftdip->mtx); -} - - -USBHFTDIPortDriver FTDIPD[HAL_USBHFTDI_MAX_PORTS]; - - -#define FTDI_COMMAND_RESET 0 -#define FTDI_RESET_ALL 0 -#define FTDI_RESET_PURGE_RX 1 -#define FTDI_RESET_PURGE_TX 2 - -#define FTDI_COMMAND_SETFLOW 2 - -#define FTDI_COMMAND_SETBAUD 3 - -#define FTDI_COMMAND_SETDATA 4 -#define FTDI_SETDATA_BREAK (0x1 << 14) - -#if 0 -#define FTDI_COMMAND_MODEMCTRL 1 -#define FTDI_COMMAND_GETMODEMSTATUS 5 /* Retrieve current value of modem status register */ -#define FTDI_COMMAND_SETEVENTCHAR 6 /* Set the event character */ -#define FTDI_COMMAND_SETERRORCHAR 7 /* Set the error character */ -#define FTDI_COMMAND_SETLATENCYTIMER 9 /* Set the latency timer */ -#define FTDI_COMMAND_GETLATENCYTIMER 10 /* Get the latency timer */ -#endif - -/* - * DATA FORMAT - * - * IN Endpoint - * - * The device reserves the first two bytes of data on this endpoint to contain - * the current values of the modem and line status registers. In the absence of - * data, the device generates a message consisting of these two status bytes - * every 40 ms - * - * Byte 0: Modem Status - * - * Offset Description - * B0 Reserved - must be 1 - * B1 Reserved - must be 0 - * B2 Reserved - must be 0 - * B3 Reserved - must be 0 - * B4 Clear to Send (CTS) - * B5 Data Set Ready (DSR) - * B6 Ring Indicator (RI) - * B7 Receive Line Signal Detect (RLSD) - * - * Byte 1: Line Status - * - * Offset Description - * B0 Data Ready (DR) - * B1 Overrun Error (OE) - * B2 Parity Error (PE) - * B3 Framing Error (FE) - * B4 Break Interrupt (BI) - * B5 Transmitter Holding Register (THRE) - * B6 Transmitter Empty (TEMT) - * B7 Error in RCVR FIFO - * - */ -#define FTDI_RS0_CTS (1 << 4) -#define FTDI_RS0_DSR (1 << 5) -#define FTDI_RS0_RI (1 << 6) -#define FTDI_RS0_RLSD (1 << 7) - -#define FTDI_RS_DR 1 -#define FTDI_RS_OE (1<<1) -#define FTDI_RS_PE (1<<2) -#define FTDI_RS_FE (1<<3) -#define FTDI_RS_BI (1<<4) -#define FTDI_RS_THRE (1<<5) -#define FTDI_RS_TEMT (1<<6) -#define FTDI_RS_FIFO (1<<7) - - -static usbh_urbstatus_t _ftdi_port_control(USBHFTDIPortDriver *ftdipp, - uint8_t bRequest, uint8_t wValue, uint8_t bHIndex, uint16_t wLength, - uint8_t *buff) { - - static const uint8_t bmRequestType[] = { - USBH_REQTYPE_VENDOR | USBH_REQTYPE_OUT | USBH_REQTYPE_DEVICE, //0 FTDI_COMMAND_RESET - USBH_REQTYPE_VENDOR | USBH_REQTYPE_OUT | USBH_REQTYPE_DEVICE, //1 FTDI_COMMAND_MODEMCTRL - USBH_REQTYPE_VENDOR | USBH_REQTYPE_OUT | USBH_REQTYPE_DEVICE, //2 FTDI_COMMAND_SETFLOW - USBH_REQTYPE_VENDOR | USBH_REQTYPE_OUT | USBH_REQTYPE_DEVICE, //3 FTDI_COMMAND_SETBAUD - USBH_REQTYPE_VENDOR | USBH_REQTYPE_OUT | USBH_REQTYPE_DEVICE, //4 FTDI_COMMAND_SETDATA - }; - - osalDbgCheck(bRequest < sizeof_array(bmRequestType)); - osalDbgCheck(bRequest != 1); - - const USBH_DEFINE_BUFFER(usbh_control_request_t, req) = { - bmRequestType[bRequest], - bRequest, - wValue, - (bHIndex << 8) | (ftdipp->ifnum + 1), - wLength - }; - - return usbhControlRequestExtended(ftdipp->ftdip->dev, &req, buff, NULL, MS2ST(1000)); -} - -static uint32_t _get_divisor(uint32_t baud, usbhftdi_type_t type) { - static const uint8_t divfrac[8] = {0, 3, 2, 4, 1, 5, 6, 7}; - uint32_t divisor; - - if (type == USBHFTDI_TYPE_A) { - uint32_t divisor3 = ((48000000UL / 2) + baud / 2) / baud; - uinfof("FTDI: desired=%dbps, real=%dbps", baud, (48000000UL / 2) / divisor3); - if ((divisor3 & 0x7) == 7) - divisor3++; /* round x.7/8 up to x+1 */ - - divisor = divisor3 >> 3; - divisor3 &= 0x7; - if (divisor3 == 1) - divisor |= 0xc000; - else if (divisor3 >= 4) - divisor |= 0x4000; - else if (divisor3 != 0) - divisor |= 0x8000; - else if (divisor == 1) - divisor = 0; /* special case for maximum baud rate */ - } else { - if (type == USBHFTDI_TYPE_B) { - divisor = ((48000000UL / 2) + baud / 2) / baud; - uinfof("FTDI: desired=%dbps, real=%dbps", baud, (48000000UL / 2) / divisor); - } else { - /* hi-speed baud rate is 10-bit sampling instead of 16-bit */ - if (baud < 1200) - baud = 1200; - divisor = (120000000UL * 8 + baud * 5) / (baud * 10); - uinfof("FTDI: desired=%dbps, real=%dbps", baud, (120000000UL * 8) / divisor / 10); - } - divisor = (divisor >> 3) | (divfrac[divisor & 0x7] << 14); - - /* Deal with special cases for highest baud rates. */ - if (divisor == 1) - divisor = 0; - else if (divisor == 0x4001) - divisor = 1; - - if (type == USBHFTDI_TYPE_H) - divisor |= 0x00020000; - } - return divisor; -} - -static usbh_urbstatus_t _set_baudrate(USBHFTDIPortDriver *ftdipp, uint32_t baudrate) { - uint32_t divisor = _get_divisor(baudrate, ftdipp->ftdip->type); - uint16_t wValue = (uint16_t)divisor; - uint16_t wIndex = (uint16_t)(divisor >> 16); - if (ftdipp->ftdip->dev->basicConfigDesc.bNumInterfaces > 1) - wIndex = (wIndex << 8) | (ftdipp->ifnum + 1); - - const USBH_DEFINE_BUFFER(usbh_control_request_t, req) = { - USBH_REQTYPE_VENDOR | USBH_REQTYPE_OUT | USBH_REQTYPE_DEVICE, - FTDI_COMMAND_SETBAUD, - wValue, - wIndex, - 0 - }; - return usbhControlRequestExtended(ftdipp->ftdip->dev, &req, NULL, NULL, MS2ST(1000)); -} - - -static void _submitOutI(USBHFTDIPortDriver *ftdipp, uint32_t len) { - udbgf("FTDI: Submit OUT %d", len); - ftdipp->oq_urb.requestedLength = len; - usbhURBObjectResetI(&ftdipp->oq_urb); - usbhURBSubmitI(&ftdipp->oq_urb); -} - -static void _out_cb(usbh_urb_t *urb) { - USBHFTDIPortDriver *const ftdipp = (USBHFTDIPortDriver *)urb->userData; - switch (urb->status) { - case USBH_URBSTATUS_OK: - ftdipp->oq_ptr = ftdipp->oq_buff; - ftdipp->oq_counter = 64; - chThdDequeueNextI(&ftdipp->oq_waiting, Q_OK); - return; - case USBH_URBSTATUS_DISCONNECTED: - uwarn("FTDI: URB OUT disconnected"); - chThdDequeueNextI(&ftdipp->oq_waiting, Q_RESET); - return; - default: - uerrf("FTDI: URB OUT status unexpected = %d", urb->status); - break; - } - usbhURBObjectResetI(&ftdipp->oq_urb); - usbhURBSubmitI(&ftdipp->oq_urb); -} - -static size_t _write_timeout(USBHFTDIPortDriver *ftdipp, const uint8_t *bp, - size_t n, systime_t timeout) { - chDbgCheck(n > 0U); - - size_t w = 0; - chSysLock(); - while (true) { - if (ftdipp->state != USBHFTDIP_STATE_READY) { - chSysUnlock(); - return w; - } - while (usbhURBIsBusy(&ftdipp->oq_urb)) { - if (chThdEnqueueTimeoutS(&ftdipp->oq_waiting, timeout) != Q_OK) { - chSysUnlock(); - return w; - } - } - - *ftdipp->oq_ptr++ = *bp++; - if (--ftdipp->oq_counter == 0) { - _submitOutI(ftdipp, 64); - chSchRescheduleS(); - } - chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ - - w++; - if (--n == 0U) - return w; - - chSysLock(); - } -} - -static msg_t _put_timeout(USBHFTDIPortDriver *ftdipp, uint8_t b, systime_t timeout) { - - chSysLock(); - if (ftdipp->state != USBHFTDIP_STATE_READY) { - chSysUnlock(); - return Q_RESET; - } - - while (usbhURBIsBusy(&ftdipp->oq_urb)) { - msg_t msg = chThdEnqueueTimeoutS(&ftdipp->oq_waiting, timeout); - if (msg < Q_OK) { - chSysUnlock(); - return msg; - } - } - - *ftdipp->oq_ptr++ = b; - if (--ftdipp->oq_counter == 0) { - _submitOutI(ftdipp, 64); - chSchRescheduleS(); - } - chSysUnlock(); - return Q_OK; -} - -static size_t _write(USBHFTDIPortDriver *ftdipp, const uint8_t *bp, size_t n) { - return _write_timeout(ftdipp, bp, n, TIME_INFINITE); -} - -static msg_t _put(USBHFTDIPortDriver *ftdipp, uint8_t b) { - return _put_timeout(ftdipp, b, TIME_INFINITE); -} - -static void _submitInI(USBHFTDIPortDriver *ftdipp) { - udbg("FTDI: Submit IN"); - usbhURBObjectResetI(&ftdipp->iq_urb); - usbhURBSubmitI(&ftdipp->iq_urb); -} - -static void _in_cb(usbh_urb_t *urb) { - USBHFTDIPortDriver *const ftdipp = (USBHFTDIPortDriver *)urb->userData; - switch (urb->status) { - case USBH_URBSTATUS_OK: - if (urb->actualLength < 2) { - uwarnf("FTDI: URB IN actualLength = %d, < 2", urb->actualLength); - } else if (urb->actualLength > 2) { - udbgf("FTDI: URB IN data len=%d, status=%02x %02x", - urb->actualLength - 2, - ((uint8_t *)urb->buff)[0], - ((uint8_t *)urb->buff)[1]); - ftdipp->iq_ptr = ftdipp->iq_buff + 2; - ftdipp->iq_counter = urb->actualLength - 2; - chThdDequeueNextI(&ftdipp->iq_waiting, Q_OK); - return; - } else { - udbgf("FTDI: URB IN no data, status=%02x %02x", - ((uint8_t *)urb->buff)[0], - ((uint8_t *)urb->buff)[1]); - return; - } - break; - case USBH_URBSTATUS_DISCONNECTED: - uwarn("FTDI: URB IN disconnected"); - chThdDequeueNextI(&ftdipp->iq_waiting, Q_RESET); - return; - default: - uerrf("FTDI: URB IN status unexpected = %d", urb->status); - break; - } - _submitInI(ftdipp); -} - -static size_t _read_timeout(USBHFTDIPortDriver *ftdipp, uint8_t *bp, - size_t n, systime_t timeout) { - size_t r = 0; - - chDbgCheck(n > 0U); - - chSysLock(); - while (true) { - if (ftdipp->state != USBHFTDIP_STATE_READY) { - chSysUnlock(); - return r; - } - while (ftdipp->iq_counter == 0) { - if (!usbhURBIsBusy(&ftdipp->iq_urb)) - _submitInI(ftdipp); - if (chThdEnqueueTimeoutS(&ftdipp->iq_waiting, timeout) != Q_OK) { - chSysUnlock(); - return r; - } - } - *bp++ = *ftdipp->iq_ptr++; - if (--ftdipp->iq_counter == 0) { - _submitInI(ftdipp); - chSchRescheduleS(); - } - chSysUnlock(); - - r++; - if (--n == 0U) - return r; - - chSysLock(); - } -} - -static msg_t _get_timeout(USBHFTDIPortDriver *ftdipp, systime_t timeout) { - uint8_t b; - - chSysLock(); - if (ftdipp->state != USBHFTDIP_STATE_READY) { - chSysUnlock(); - return Q_RESET; - } - while (ftdipp->iq_counter == 0) { - if (!usbhURBIsBusy(&ftdipp->iq_urb)) - _submitInI(ftdipp); - msg_t msg = chThdEnqueueTimeoutS(&ftdipp->iq_waiting, timeout); - if (msg < Q_OK) { - chSysUnlock(); - return msg; - } - } - b = *ftdipp->iq_ptr++; - if (--ftdipp->iq_counter == 0) { - _submitInI(ftdipp); - chSchRescheduleS(); - } - chSysUnlock(); - - return (msg_t)b; -} - -static msg_t _get(USBHFTDIPortDriver *ftdipp) { - return _get_timeout(ftdipp, TIME_INFINITE); -} - -static size_t _read(USBHFTDIPortDriver *ftdipp, uint8_t *bp, size_t n) { - return _read_timeout(ftdipp, bp, n, TIME_INFINITE); -} - -static void _vt(void *p) { - USBHFTDIPortDriver *const ftdipp = (USBHFTDIPortDriver *)p; - chSysLockFromISR(); - uint32_t len = ftdipp->oq_ptr - ftdipp->oq_buff; - if (len && !usbhURBIsBusy(&ftdipp->oq_urb)) { - _submitOutI(ftdipp, len); - } - if ((ftdipp->iq_counter == 0) && !usbhURBIsBusy(&ftdipp->iq_urb)) { - _submitInI(ftdipp); - } - chVTSetI(&ftdipp->vt, MS2ST(16), _vt, ftdipp); - chSysUnlockFromISR(); -} - -static const struct FTDIPortDriverVMT async_channel_vmt = { - (size_t (*)(void *, const uint8_t *, size_t))_write, - (size_t (*)(void *, uint8_t *, size_t))_read, - (msg_t (*)(void *, uint8_t))_put, - (msg_t (*)(void *))_get, - (msg_t (*)(void *, uint8_t, systime_t))_put_timeout, - (msg_t (*)(void *, systime_t))_get_timeout, - (size_t (*)(void *, const uint8_t *, size_t, systime_t))_write_timeout, - (size_t (*)(void *, uint8_t *, size_t, systime_t))_read_timeout -}; - - -static void _stop(USBHFTDIPortDriver *ftdipp) { - osalSysLock(); - chVTResetI(&ftdipp->vt); - usbhEPCloseS(&ftdipp->epin); - usbhEPCloseS(&ftdipp->epout); - chThdDequeueAllI(&ftdipp->iq_waiting, Q_RESET); - chThdDequeueAllI(&ftdipp->oq_waiting, Q_RESET); - osalOsRescheduleS(); - ftdipp->state = USBHFTDIP_STATE_ACTIVE; - osalSysUnlock(); -} - -void usbhftdipStop(USBHFTDIPortDriver *ftdipp) { - osalDbgCheck((ftdipp->state == USBHFTDIP_STATE_ACTIVE) - || (ftdipp->state == USBHFTDIP_STATE_READY)); - - if (ftdipp->state == USBHFTDIP_STATE_ACTIVE) { - return; - } - - osalMutexLock(&ftdipp->ftdip->mtx); - _stop(ftdipp); - osalMutexUnlock(&ftdipp->ftdip->mtx); -} - -void usbhftdipStart(USBHFTDIPortDriver *ftdipp, const USBHFTDIPortConfig *config) { - static const USBHFTDIPortConfig default_config = { - HAL_USBHFTDI_DEFAULT_SPEED, - HAL_USBHFTDI_DEFAULT_FRAMING, - HAL_USBHFTDI_DEFAULT_HANDSHAKE, - HAL_USBHFTDI_DEFAULT_XON, - HAL_USBHFTDI_DEFAULT_XOFF - }; - - osalDbgCheck((ftdipp->state == USBHFTDIP_STATE_ACTIVE) - || (ftdipp->state == USBHFTDIP_STATE_READY)); - - if (ftdipp->state == USBHFTDIP_STATE_READY) - return; - - osalMutexLock(&ftdipp->ftdip->mtx); - if (config == NULL) - config = &default_config; - - uint16_t wValue = 0; - _ftdi_port_control(ftdipp, FTDI_COMMAND_RESET, FTDI_RESET_ALL, 0, 0, NULL); - _set_baudrate(ftdipp, config->speed); - _ftdi_port_control(ftdipp, FTDI_COMMAND_SETDATA, config->framing, 0, 0, NULL); - if (config->handshake & USBHFTDI_HANDSHAKE_XON_XOFF) - wValue = (config->xoff_character << 8) | config->xon_character; - _ftdi_port_control(ftdipp, FTDI_COMMAND_SETFLOW, wValue, config->handshake, 0, NULL); - - usbhURBObjectInit(&ftdipp->oq_urb, &ftdipp->epout, _out_cb, ftdipp, ftdipp->oq_buff, 0); - chThdQueueObjectInit(&ftdipp->oq_waiting); - ftdipp->oq_counter = 64; - ftdipp->oq_ptr = ftdipp->oq_buff; - usbhEPOpen(&ftdipp->epout); - - usbhURBObjectInit(&ftdipp->iq_urb, &ftdipp->epin, _in_cb, ftdipp, ftdipp->iq_buff, 64); - chThdQueueObjectInit(&ftdipp->iq_waiting); - ftdipp->iq_counter = 0; - ftdipp->iq_ptr = ftdipp->iq_buff; - usbhEPOpen(&ftdipp->epin); - osalSysLock(); - usbhURBSubmitI(&ftdipp->iq_urb); - osalSysUnlock(); - - chVTObjectInit(&ftdipp->vt); - chVTSet(&ftdipp->vt, MS2ST(16), _vt, ftdipp); - - ftdipp->state = USBHFTDIP_STATE_READY; - osalMutexUnlock(&ftdipp->ftdip->mtx); -} - -void usbhftdiObjectInit(USBHFTDIDriver *ftdip) { - osalDbgCheck(ftdip != NULL); - memset(ftdip, 0, sizeof(*ftdip)); - ftdip->info = &usbhftdiClassDriverInfo; - osalMutexObjectInit(&ftdip->mtx); -} - -void usbhftdipObjectInit(USBHFTDIPortDriver *ftdipp) { - osalDbgCheck(ftdipp != NULL); - memset(ftdipp, 0, sizeof(*ftdipp)); - ftdipp->vmt = &async_channel_vmt; - ftdipp->state = USBHFTDIP_STATE_STOP; -} - -#endif diff --git a/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_hub.c b/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_hub.c deleted file mode 100644 index 7fdcef1..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_hub.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio - Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail) - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#include "hal.h" -#include "hal_usbh.h" -#include "usbh/internal.h" - -#if HAL_USBH_USE_HUB - -#if !HAL_USE_USBH -#error "USBHHUB needs HAL_USE_USBH" -#endif - -#include -#include "usbh/dev/hub.h" - -#if USBHHUB_DEBUG_ENABLE_TRACE -#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define udbgf(f, ...) do {} while(0) -#define udbg(f, ...) do {} while(0) -#endif - -#if USBHHUB_DEBUG_ENABLE_INFO -#define uinfof(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define uinfo(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define uinfof(f, ...) do {} while(0) -#define uinfo(f, ...) do {} while(0) -#endif - -#if USBHHUB_DEBUG_ENABLE_WARNINGS -#define uwarnf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define uwarn(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define uwarnf(f, ...) do {} while(0) -#define uwarn(f, ...) do {} while(0) -#endif - -#if USBHHUB_DEBUG_ENABLE_ERRORS -#define uerrf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define uerr(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define uerrf(f, ...) do {} while(0) -#define uerr(f, ...) do {} while(0) -#endif - - -USBHHubDriver USBHHUBD[HAL_USBHHUB_MAX_INSTANCES]; -usbh_port_t USBHPorts[HAL_USBHHUB_MAX_PORTS]; - -static usbh_baseclassdriver_t *hub_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); -static void hub_unload(usbh_baseclassdriver_t *drv); -static const usbh_classdriver_vmt_t usbhhubClassDriverVMT = { - hub_load, - hub_unload -}; -const usbh_classdriverinfo_t usbhhubClassDriverInfo = { - 0x09, 0x00, -1, "HUB", &usbhhubClassDriverVMT -}; - - -void _usbhub_port_object_init(usbh_port_t *port, USBHDriver *usbh, - USBHHubDriver *hub, uint8_t number) { - memset(port, 0, sizeof(*port)); - port->number = number; - port->device.host = usbh; - port->hub = hub; -} - -usbh_urbstatus_t usbhhubControlRequest(USBHDriver *host, USBHHubDriver *hub, - uint8_t bmRequestType, - uint8_t bRequest, - uint16_t wValue, - uint16_t wIndex, - uint16_t wLength, - uint8_t *buf) { - if (hub == NULL) - return usbh_lld_root_hub_request(host, bmRequestType, bRequest, wValue, wIndex, wLength, buf); - - return usbhControlRequest(hub->dev, - bmRequestType, bRequest, wValue, wIndex, wLength, buf); -} - - -static void _urb_complete(usbh_urb_t *urb) { - - USBHHubDriver *const hubdp = (USBHHubDriver *)urb->userData; - switch (urb->status) { - case USBH_URBSTATUS_TIMEOUT: - /* the device NAKed */ - udbg("HUB: no info"); - hubdp->statuschange = 0; - break; - case USBH_URBSTATUS_OK: { - uint8_t len = hubdp->hubDesc.bNbrPorts / 8 + 1; - if (urb->actualLength != len) { - uwarnf("Expected %d status change bytes but got %d", len, urb->actualLength); - } - - if (urb->actualLength < len) - len = urb->actualLength; - - if (len > 4) - len = 4; - - uint8_t *sc = (uint8_t *)&hubdp->statuschange; - uint8_t *r = hubdp->scbuff; - while (len--) - *sc++ |= *r++; - - uinfof("HUB: change, %08x", hubdp->statuschange); - } break; - case USBH_URBSTATUS_DISCONNECTED: - uwarn("HUB: URB disconnected, aborting poll"); - return; - default: - uerrf("HUB: URB status unexpected = %d", urb->status); - break; - } - - usbhURBObjectResetI(urb); - usbhURBSubmitI(urb); -} - -static usbh_baseclassdriver_t *hub_load(usbh_device_t *dev, - const uint8_t *descriptor, uint16_t rem) { - int i; - - USBHHubDriver *hubdp; - - if ((rem < descriptor[0]) || (descriptor[1] != USBH_DT_DEVICE)) - return NULL; - - if (dev->devDesc.bDeviceProtocol != 0) - return NULL; - - generic_iterator_t iep, icfg; - if_iterator_t iif; - - cfg_iter_init(&icfg, dev->fullConfigurationDescriptor, - dev->basicConfigDesc.wTotalLength); - - if_iter_init(&iif, &icfg); - if (!iif.valid) - return NULL; - const usbh_interface_descriptor_t *const ifdesc = if_get(&iif); - if ((ifdesc->bInterfaceClass != 0x09) - || (ifdesc->bInterfaceSubClass != 0x00) - || (ifdesc->bInterfaceProtocol != 0x00)) { - return NULL; - } - - ep_iter_init(&iep, &iif); - if (!iep.valid) - return NULL; - const usbh_endpoint_descriptor_t *const epdesc = ep_get(&iep); - if ((epdesc->bmAttributes & 0x03) != USBH_EPTYPE_INT) { - return NULL; - } - - - /* alloc driver */ - for (i = 0; i < HAL_USBHHUB_MAX_INSTANCES; i++) { - if (USBHHUBD[i].dev == NULL) { - hubdp = &USBHHUBD[i]; - goto alloc_ok; - } - } - - uwarn("Can't alloc HUB driver"); - - /* can't alloc */ - return NULL; - -alloc_ok: - /* initialize the driver's variables */ - hubdp->epint.status = USBH_EPSTATUS_UNINITIALIZED; - hubdp->dev = dev; - hubdp->ports = 0; - - usbhEPSetName(&dev->ctrl, "HUB[CTRL]"); - - /* read Hub descriptor */ - uinfo("Read Hub descriptor"); - if (usbhhubControlRequest(dev->host, hubdp, - USBH_REQTYPE_IN | USBH_REQTYPE_CLASS | USBH_REQTYPE_DEVICE, - USBH_REQ_GET_DESCRIPTOR, - (USBH_DT_HUB << 8), 0, sizeof(hubdp->hubDesc), - (uint8_t *)&hubdp->hubDesc) != USBH_URBSTATUS_OK) { - hubdp->dev = NULL; - return NULL; - } - - const usbh_hub_descriptor_t *const hubdesc = &hubdp->hubDesc; - - uinfof("Hub descriptor loaded; %d ports, wHubCharacteristics=%04x, bPwrOn2PwrGood=%d, bHubContrCurrent=%d", - hubdesc->bNbrPorts, - hubdesc->wHubCharacteristics, - hubdesc->bPwrOn2PwrGood, - hubdesc->bHubContrCurrent); - - /* Alloc ports */ - uint8_t ports = hubdesc->bNbrPorts; - for (i = 0; (ports > 0) && (i < HAL_USBHHUB_MAX_PORTS); i++) { - if (USBHPorts[i].hub == NULL) { - uinfof("Alloc port %d", ports); - _usbhub_port_object_init(&USBHPorts[i], dev->host, hubdp, ports); - USBHPorts[i].next = hubdp->ports; - hubdp->ports = &USBHPorts[i]; - --ports; - } - } - - if (ports) { - uwarn("Could not alloc all ports"); - } - - /* link hub to the host's list */ - list_add_tail(&hubdp->node, &dev->host->hubs); - - /* enable power to ports */ - usbh_port_t *port = hubdp->ports; - while (port) { - uinfof("Enable power for port %d", port->number); - usbhhubSetFeaturePort(port, USBH_PORT_FEAT_POWER); - port = port->next; - } - - if (hubdesc->bPwrOn2PwrGood) - osalThreadSleepMilliseconds(2 * hubdesc->bPwrOn2PwrGood); - - /* initialize the status change endpoint and trigger the first transfer */ - usbhEPObjectInit(&hubdp->epint, dev, epdesc); - usbhEPSetName(&hubdp->epint, "HUB[INT ]"); - usbhEPOpen(&hubdp->epint); - - usbhURBObjectInit(&hubdp->urb, &hubdp->epint, - _urb_complete, hubdp, hubdp->scbuff, - (hubdesc->bNbrPorts + 8) / 8); - - osalSysLock(); - usbhURBSubmitI(&hubdp->urb); - osalOsRescheduleS(); - osalSysUnlock(); - - return (usbh_baseclassdriver_t *)hubdp; -} - -static void hub_unload(usbh_baseclassdriver_t *drv) { - osalDbgCheck(drv != NULL); - USBHHubDriver *const hubdp = (USBHHubDriver *)drv; - - /* close the status change endpoint (this cancels ongoing URBs) */ - osalSysLock(); - usbhEPCloseS(&hubdp->epint); - osalSysUnlock(); - - /* de-alloc ports and unload drivers */ - usbh_port_t *port = hubdp->ports; - while (port) { - _usbh_port_disconnected(port); - port->hub = NULL; - port = port->next; - } - - /* unlink the hub from the host's list */ - list_del(&hubdp->node); - -} - -void usbhhubObjectInit(USBHHubDriver *hubdp) { - osalDbgCheck(hubdp != NULL); - memset(hubdp, 0, sizeof(*hubdp)); - hubdp->info = &usbhhubClassDriverInfo; -} -#else - -#if HAL_USE_USBH -void _usbhub_port_object_init(usbh_port_t *port, USBHDriver *usbh, uint8_t number) { - memset(port, 0, sizeof(*port)); - port->number = number; - port->device.host = usbh; -} -#endif - -#endif diff --git a/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_msd.c b/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_msd.c deleted file mode 100644 index 6869a74..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_msd.c +++ /dev/null @@ -1,939 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio - Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail) - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#include "hal.h" -#include "hal_usbh.h" - -#if HAL_USBH_USE_MSD - -#if !HAL_USE_USBH -#error "USBHMSD needs USBH" -#endif - -#include -#include "usbh/dev/msd.h" -#include "usbh/internal.h" - -//#pragma GCC optimize("Og") - - -#if USBHMSD_DEBUG_ENABLE_TRACE -#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define udbgf(f, ...) do {} while(0) -#define udbg(f, ...) do {} while(0) -#endif - -#if USBHMSD_DEBUG_ENABLE_INFO -#define uinfof(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define uinfo(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define uinfof(f, ...) do {} while(0) -#define uinfo(f, ...) do {} while(0) -#endif - -#if USBHMSD_DEBUG_ENABLE_WARNINGS -#define uwarnf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define uwarn(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define uwarnf(f, ...) do {} while(0) -#define uwarn(f, ...) do {} while(0) -#endif - -#if USBHMSD_DEBUG_ENABLE_ERRORS -#define uerrf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define uerr(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define uerrf(f, ...) do {} while(0) -#define uerr(f, ...) do {} while(0) -#endif - - - - - -/*===========================================================================*/ -/* USB Class driver loader for MSD */ -/*===========================================================================*/ - -USBHMassStorageDriver USBHMSD[HAL_USBHMSD_MAX_INSTANCES]; - -static usbh_baseclassdriver_t *_msd_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem); -static void _msd_unload(usbh_baseclassdriver_t *drv); - -static const usbh_classdriver_vmt_t class_driver_vmt = { - _msd_load, - _msd_unload -}; - -const usbh_classdriverinfo_t usbhmsdClassDriverInfo = { - 0x08, 0x06, 0x50, "MSD", &class_driver_vmt -}; - -#define MSD_REQ_RESET 0xFF -#define MSD_GET_MAX_LUN 0xFE - -static usbh_baseclassdriver_t *_msd_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem) { - int i; - USBHMassStorageDriver *msdp; - uint8_t luns; // should declare it here to eliminate 'control bypass initialization' warning - usbh_urbstatus_t stat; // should declare it here to eliminate 'control bypass initialization' warning - - if ((rem < descriptor[0]) || (descriptor[1] != USBH_DT_INTERFACE)) - return NULL; - - const usbh_interface_descriptor_t * const ifdesc = (const usbh_interface_descriptor_t *)descriptor; - - if ((ifdesc->bAlternateSetting != 0) - || (ifdesc->bNumEndpoints < 2) - || (ifdesc->bInterfaceSubClass != 0x06) - || (ifdesc->bInterfaceProtocol != 0x50)) { - return NULL; - } - - /* alloc driver */ - for (i = 0; i < HAL_USBHMSD_MAX_INSTANCES; i++) { - if (USBHMSD[i].dev == NULL) { - msdp = &USBHMSD[i]; - goto alloc_ok; - } - } - - uwarn("Can't alloc MSD driver"); - - /* can't alloc */ - return NULL; - -alloc_ok: - /* initialize the driver's variables */ - msdp->epin.status = USBH_EPSTATUS_UNINITIALIZED; - msdp->epout.status = USBH_EPSTATUS_UNINITIALIZED; - msdp->max_lun = 0; - msdp->tag = 0; - msdp->luns = 0; - msdp->ifnum = ifdesc->bInterfaceNumber; - usbhEPSetName(&dev->ctrl, "MSD[CTRL]"); - - /* parse the configuration descriptor */ - if_iterator_t iif; - generic_iterator_t iep; - iif.iad = 0; - iif.curr = descriptor; - iif.rem = rem; - for (ep_iter_init(&iep, &iif); iep.valid; ep_iter_next(&iep)) { - const usbh_endpoint_descriptor_t *const epdesc = ep_get(&iep); - if ((epdesc->bEndpointAddress & 0x80) && (epdesc->bmAttributes == USBH_EPTYPE_BULK)) { - uinfof("BULK IN endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress); - usbhEPObjectInit(&msdp->epin, dev, epdesc); - usbhEPSetName(&msdp->epin, "MSD[BIN ]"); - } else if (((epdesc->bEndpointAddress & 0x80) == 0) - && (epdesc->bmAttributes == USBH_EPTYPE_BULK)) { - uinfof("BULK OUT endpoint found: bEndpointAddress=%02x", epdesc->bEndpointAddress); - usbhEPObjectInit(&msdp->epout, dev, epdesc); - usbhEPSetName(&msdp->epout, "MSD[BOUT]"); - } else { - uinfof("unsupported endpoint found: bEndpointAddress=%02x, bmAttributes=%02x", - epdesc->bEndpointAddress, epdesc->bmAttributes); - } - } - if ((msdp->epin.status != USBH_EPSTATUS_CLOSED) || (msdp->epout.status != USBH_EPSTATUS_CLOSED)) { - goto deinit; - } - - /* read the number of LUNs */ - uinfo("Reading Max LUN:"); - USBH_DEFINE_BUFFER(uint8_t, buff[4]); - stat = usbhControlRequest(dev, - USBH_CLASSIN(USBH_REQTYPE_INTERFACE, MSD_GET_MAX_LUN, 0, msdp->ifnum), - 1, buff); - if (stat == USBH_URBSTATUS_OK) { - msdp->max_lun = buff[0] + 1; - uinfof("\tmax_lun = %d", msdp->max_lun); - if (msdp->max_lun > HAL_USBHMSD_MAX_LUNS) { - msdp->max_lun = HAL_USBHMSD_MAX_LUNS; - uwarnf("\tUsing max_lun = %d", msdp->max_lun); - } - } else if (stat == USBH_URBSTATUS_STALL) { - uwarn("\tStall, max_lun = 1"); - msdp->max_lun = 1; - } else { - uerr("\tError"); - goto deinit; - } - - /* open the bulk IN/OUT endpoints */ - usbhEPOpen(&msdp->epin); - usbhEPOpen(&msdp->epout); - - /* Alloc one block device per logical unit found */ - luns = msdp->max_lun; - for (i = 0; (luns > 0) && (i < HAL_USBHMSD_MAX_LUNS); i++) { - if (MSBLKD[i].msdp == NULL) { - /* link the new block driver to the list */ - MSBLKD[i].next = msdp->luns; - msdp->luns = &MSBLKD[i]; - MSBLKD[i].msdp = msdp; - - osalSysLock(); - MSBLKD[i].state = BLK_ACTIVE; /* transition directly to active, instead of BLK_STOP */ - osalSysUnlock(); - - /* connect the LUN (TODO: review if it's best to leave the LUN disconnected) */ - usbhmsdLUNConnect(&MSBLKD[i]); - luns--; - } - } - - return (usbh_baseclassdriver_t *)msdp; - -deinit: - /* Here, the enpoints are closed, and the driver is unlinked */ - return NULL; -} - -static void _msd_unload(usbh_baseclassdriver_t *drv) { - osalDbgCheck(drv != NULL); - USBHMassStorageDriver *const msdp = (USBHMassStorageDriver *)drv; - USBHMassStorageLUNDriver *lunp = msdp->luns; - - osalMutexLock(&msdp->mtx); - osalSysLock(); - usbhEPCloseS(&msdp->epin); - usbhEPCloseS(&msdp->epout); - while (lunp) { - lunp->state = BLK_STOP; - lunp = lunp->next; - } - osalSysUnlock(); - osalMutexUnlock(&msdp->mtx); - - /* now that the LUNs are idle, deinit them */ - lunp = msdp->luns; - osalSysLock(); - while (lunp) { - usbhmsdLUNObjectInit(lunp); - lunp = lunp->next; - } - osalSysUnlock(); -} - - -/*===========================================================================*/ -/* MSD Class driver operations (Bulk-Only transport) */ -/*===========================================================================*/ - - - -/* USB Bulk Only Transport SCSI Command block wrapper */ -PACKED_STRUCT { - uint32_t dCBWSignature; - uint32_t dCBWTag; - uint32_t dCBWDataTransferLength; - uint8_t bmCBWFlags; - uint8_t bCBWLUN; - uint8_t bCBWCBLength; - uint8_t CBWCB[16]; -} msd_cbw_t; -#define MSD_CBW_SIGNATURE 0x43425355 -#define MSD_CBWFLAGS_D2H 0x80 -#define MSD_CBWFLAGS_H2D 0x00 - - -/* USB Bulk Only Transport SCSI Command status wrapper */ -PACKED_STRUCT { - uint32_t dCSWSignature; - uint32_t dCSWTag; - uint32_t dCSWDataResidue; - uint8_t bCSWStatus; -} msd_csw_t; -#define MSD_CSW_SIGNATURE 0x53425355 - - -typedef union { - msd_cbw_t cbw; - msd_csw_t csw; -} msd_transaction_t; - -typedef enum { - MSD_TRANSACTIONRESULT_OK, - MSD_TRANSACTIONRESULT_DISCONNECTED, - MSD_TRANSACTIONRESULT_STALL, - MSD_TRANSACTIONRESULT_BUS_ERROR, - MSD_TRANSACTIONRESULT_SYNC_ERROR -} msd_transaction_result_t; - -typedef enum { - MSD_COMMANDRESULT_PASSED = 0, - MSD_COMMANDRESULT_FAILED = 1, - MSD_COMMANDRESULT_PHASE_ERROR = 2 -} msd_command_result_t; - -typedef struct { - msd_transaction_result_t tres; - msd_command_result_t cres; -} msd_result_t; - - -/* ----------------------------------------------------- */ -/* SCSI Commands */ -/* ----------------------------------------------------- */ - -/* Read 10 and Write 10 */ -#define SCSI_CMD_READ_10 0x28 -#define SCSI_CMD_WRITE_10 0x2A - -/* Request sense */ -#define SCSI_CMD_REQUEST_SENSE 0x03 -PACKED_STRUCT { - uint8_t byte[18]; -} scsi_sense_response_t; - -#define SCSI_SENSE_KEY_GOOD 0x00 -#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01 -#define SCSI_SENSE_KEY_NOT_READY 0x02 -#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03 -#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04 -#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05 -#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06 -#define SCSI_SENSE_KEY_DATA_PROTECT 0x07 -#define SCSI_SENSE_KEY_BLANK_CHECK 0x08 -#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09 -#define SCSI_SENSE_KEY_COPY_ABORTED 0x0A -#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B -#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D -#define SCSI_SENSE_KEY_MISCOMPARE 0x0E -#define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00 -#define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04 -#define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24 -#define SCSI_ASENSE_NOT_READY_TO_READY_CHANGE 0x28 -#define SCSI_ASENSE_WRITE_PROTECTED 0x27 -#define SCSI_ASENSE_FORMAT_ERROR 0x31 -#define SCSI_ASENSE_INVALID_COMMAND 0x20 -#define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21 -#define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A -#define SCSI_ASENSEQ_NO_QUALIFIER 0x00 -#define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01 -#define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02 -#define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07 - -/* Inquiry */ -#define SCSI_CMD_INQUIRY 0x12 -PACKED_STRUCT { - uint8_t peripheral; - uint8_t removable; - uint8_t version; - uint8_t response_data_format; - uint8_t additional_length; - uint8_t sccstp; - uint8_t bqueetc; - uint8_t cmdque; - uint8_t vendorID[8]; - uint8_t productID[16]; - uint8_t productRev[4]; -} scsi_inquiry_response_t; - -/* Read Capacity 10 */ -#define SCSI_CMD_READ_CAPACITY_10 0x25 -PACKED_STRUCT { - uint32_t last_block_addr; - uint32_t block_size; -} scsi_readcapacity10_response_t; - -/* Start/Stop Unit */ -#define SCSI_CMD_START_STOP_UNIT 0x1B -PACKED_STRUCT { - uint8_t op_code; - uint8_t lun_immed; - uint8_t res1; - uint8_t res2; - uint8_t loej_start; - uint8_t control; -} scsi_startstopunit_request_t; - -/* test unit ready */ -#define SCSI_CMD_TEST_UNIT_READY 0x00 - -/* Other commands, TODO: use or remove them -#define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E -#define SCSI_CMD_VERIFY_10 0x2F -#define SCSI_CMD_SEND_DIAGNOSTIC 0x1D -#define SCSI_CMD_MODE_SENSE_6 0x1A -*/ - -static inline void _prepare_cbw(msd_transaction_t *tran, USBHMassStorageLUNDriver *lunp) { - tran->cbw.bCBWLUN = (uint8_t)(lunp - &lunp->msdp->luns[0]); - memset(&tran->cbw.CBWCB, 0, sizeof(tran->cbw.CBWCB)); -} - -static msd_transaction_result_t _msd_transaction(msd_transaction_t *tran, USBHMassStorageLUNDriver *lunp, void *data) { - - uint32_t actual_len; - usbh_urbstatus_t status; - - tran->cbw.dCBWSignature = MSD_CBW_SIGNATURE; - tran->cbw.dCBWTag = ++lunp->msdp->tag; - - /* control phase */ - status = usbhBulkTransfer(&lunp->msdp->epout, &tran->cbw, - sizeof(tran->cbw), &actual_len, MS2ST(1000)); - - if (status == USBH_URBSTATUS_CANCELLED) { - uerr("\tMSD: Control phase: USBH_URBSTATUS_CANCELLED"); - return MSD_TRANSACTIONRESULT_DISCONNECTED; - } else if (status == USBH_URBSTATUS_STALL) { - uerr("\tMSD: Control phase: USBH_URBSTATUS_STALL"); - return MSD_TRANSACTIONRESULT_STALL; - } else if (status != USBH_URBSTATUS_OK) { - uerrf("\tMSD: Control phase: status = %d, != OK", status); - return MSD_TRANSACTIONRESULT_BUS_ERROR; - } else if (actual_len != sizeof(tran->cbw)) { - uerrf("\tMSD: Control phase: wrong actual_len = %d", actual_len); - return MSD_TRANSACTIONRESULT_BUS_ERROR; - } - - - /* data phase */ - if (tran->cbw.dCBWDataTransferLength) { - status = usbhBulkTransfer( - tran->cbw.bmCBWFlags & MSD_CBWFLAGS_D2H ? &lunp->msdp->epin : &lunp->msdp->epout, - data, - tran->cbw.dCBWDataTransferLength, - &actual_len, MS2ST(20000)); - - if (status == USBH_URBSTATUS_CANCELLED) { - uerr("\tMSD: Data phase: USBH_URBSTATUS_CANCELLED"); - return MSD_TRANSACTIONRESULT_DISCONNECTED; - } else if (status == USBH_URBSTATUS_STALL) { - uerr("\tMSD: Data phase: USBH_URBSTATUS_STALL"); - return MSD_TRANSACTIONRESULT_STALL; - } else if (status != USBH_URBSTATUS_OK) { - uerrf("\tMSD: Data phase: status = %d, != OK", status); - return MSD_TRANSACTIONRESULT_BUS_ERROR; - } else if (actual_len != tran->cbw.dCBWDataTransferLength) { - uerrf("\tMSD: Data phase: wrong actual_len = %d", actual_len); - return MSD_TRANSACTIONRESULT_BUS_ERROR; - } - } - - - /* status phase */ - status = usbhBulkTransfer(&lunp->msdp->epin, &tran->csw, - sizeof(tran->csw), &actual_len, MS2ST(1000)); - - if (status == USBH_URBSTATUS_CANCELLED) { - uerr("\tMSD: Status phase: USBH_URBSTATUS_CANCELLED"); - return MSD_TRANSACTIONRESULT_DISCONNECTED; - } else if (status == USBH_URBSTATUS_STALL) { - uerr("\tMSD: Status phase: USBH_URBSTATUS_STALL"); - return MSD_TRANSACTIONRESULT_STALL; - } else if (status != USBH_URBSTATUS_OK) { - uerrf("\tMSD: Status phase: status = %d, != OK", status); - return MSD_TRANSACTIONRESULT_BUS_ERROR; - } else if (actual_len != sizeof(tran->csw)) { - uerrf("\tMSD: Status phase: wrong actual_len = %d", actual_len); - return MSD_TRANSACTIONRESULT_BUS_ERROR; - } else if (tran->csw.dCSWSignature != MSD_CSW_SIGNATURE) { - uerr("\tMSD: Status phase: wrong signature"); - return MSD_TRANSACTIONRESULT_BUS_ERROR; - } else if (tran->csw.dCSWTag != lunp->msdp->tag) { - uerrf("\tMSD: Status phase: wrong tag (expected %d, got %d)", - lunp->msdp->tag, tran->csw.dCSWTag); - return MSD_TRANSACTIONRESULT_SYNC_ERROR; - } - - if (tran->csw.dCSWDataResidue) { - uwarnf("\tMSD: Residue=%d", tran->csw.dCSWDataResidue); - } - - return MSD_TRANSACTIONRESULT_OK; -} - - -static msd_result_t scsi_inquiry(USBHMassStorageLUNDriver *lunp, scsi_inquiry_response_t *resp) { - msd_transaction_t transaction; - msd_result_t res; - - _prepare_cbw(&transaction, lunp); - transaction.cbw.dCBWDataTransferLength = sizeof(scsi_inquiry_response_t); - transaction.cbw.bmCBWFlags = MSD_CBWFLAGS_D2H; - transaction.cbw.bCBWCBLength = 6; - transaction.cbw.CBWCB[0] = SCSI_CMD_INQUIRY; - transaction.cbw.CBWCB[4] = sizeof(scsi_inquiry_response_t); - - res.tres = _msd_transaction(&transaction, lunp, resp); - if (res.tres == MSD_TRANSACTIONRESULT_OK) { - res.cres = (msd_command_result_t) transaction.csw.bCSWStatus; - } - return res; -} - -static msd_result_t scsi_requestsense(USBHMassStorageLUNDriver *lunp, scsi_sense_response_t *resp) { - msd_transaction_t transaction; - msd_result_t res; - - _prepare_cbw(&transaction, lunp); - transaction.cbw.dCBWDataTransferLength = sizeof(scsi_sense_response_t); - transaction.cbw.bmCBWFlags = MSD_CBWFLAGS_D2H; - transaction.cbw.bCBWCBLength = 12; - transaction.cbw.CBWCB[0] = SCSI_CMD_REQUEST_SENSE; - transaction.cbw.CBWCB[4] = sizeof(scsi_sense_response_t); - - res.tres = _msd_transaction(&transaction, lunp, resp); - if (res.tres == MSD_TRANSACTIONRESULT_OK) { - res.cres = (msd_command_result_t) transaction.csw.bCSWStatus; - } - return res; -} - -static msd_result_t scsi_testunitready(USBHMassStorageLUNDriver *lunp) { - msd_transaction_t transaction; - msd_result_t res; - - _prepare_cbw(&transaction, lunp); - transaction.cbw.dCBWDataTransferLength = 0; - transaction.cbw.bmCBWFlags = MSD_CBWFLAGS_D2H; - transaction.cbw.bCBWCBLength = 6; - transaction.cbw.CBWCB[0] = SCSI_CMD_TEST_UNIT_READY; - - res.tres = _msd_transaction(&transaction, lunp, NULL); - if (res.tres == MSD_TRANSACTIONRESULT_OK) { - res.cres = (msd_command_result_t) transaction.csw.bCSWStatus; - } - return res; -} - -static msd_result_t scsi_readcapacity10(USBHMassStorageLUNDriver *lunp, scsi_readcapacity10_response_t *resp) { - msd_transaction_t transaction; - msd_result_t res; - - _prepare_cbw(&transaction, lunp); - transaction.cbw.dCBWDataTransferLength = sizeof(scsi_readcapacity10_response_t); - transaction.cbw.bmCBWFlags = MSD_CBWFLAGS_D2H; - transaction.cbw.bCBWCBLength = 12; - transaction.cbw.CBWCB[0] = SCSI_CMD_READ_CAPACITY_10; - - res.tres = _msd_transaction(&transaction, lunp, resp); - if (res.tres == MSD_TRANSACTIONRESULT_OK) { - res.cres = (msd_command_result_t) transaction.csw.bCSWStatus; - } - return res; -} - - -static msd_result_t scsi_read10(USBHMassStorageLUNDriver *lunp, uint32_t lba, uint16_t n, uint8_t *data) { - msd_transaction_t transaction; - msd_result_t res; - - _prepare_cbw(&transaction, lunp); - transaction.cbw.dCBWDataTransferLength = n * lunp->info.blk_size; - transaction.cbw.bmCBWFlags = MSD_CBWFLAGS_D2H; - transaction.cbw.bCBWCBLength = 10; - transaction.cbw.CBWCB[0] = SCSI_CMD_READ_10; - transaction.cbw.CBWCB[2] = (uint8_t)(lba >> 24); - transaction.cbw.CBWCB[3] = (uint8_t)(lba >> 16); - transaction.cbw.CBWCB[4] = (uint8_t)(lba >> 8); - transaction.cbw.CBWCB[5] = (uint8_t)(lba); - transaction.cbw.CBWCB[7] = (uint8_t)(n >> 8); - transaction.cbw.CBWCB[8] = (uint8_t)(n); - - res.tres = _msd_transaction(&transaction, lunp, data); - if (res.tres == MSD_TRANSACTIONRESULT_OK) { - res.cres = (msd_command_result_t) transaction.csw.bCSWStatus; - } - return res; -} - -static msd_result_t scsi_write10(USBHMassStorageLUNDriver *lunp, uint32_t lba, uint16_t n, const uint8_t *data) { - msd_transaction_t transaction; - msd_result_t res; - - _prepare_cbw(&transaction, lunp); - transaction.cbw.dCBWDataTransferLength = n * lunp->info.blk_size; - transaction.cbw.bmCBWFlags = MSD_CBWFLAGS_H2D; - transaction.cbw.bCBWCBLength = 10; - transaction.cbw.CBWCB[0] = SCSI_CMD_WRITE_10; - transaction.cbw.CBWCB[2] = (uint8_t)(lba >> 24); - transaction.cbw.CBWCB[3] = (uint8_t)(lba >> 16); - transaction.cbw.CBWCB[4] = (uint8_t)(lba >> 8); - transaction.cbw.CBWCB[5] = (uint8_t)(lba); - transaction.cbw.CBWCB[7] = (uint8_t)(n >> 8); - transaction.cbw.CBWCB[8] = (uint8_t)(n); - - res.tres = _msd_transaction(&transaction, lunp, (uint8_t *)data); - if (res.tres == MSD_TRANSACTIONRESULT_OK) { - res.cres = (msd_command_result_t) transaction.csw.bCSWStatus; - } - return res; -} - - - -/*===========================================================================*/ -/* Block driver data/functions */ -/*===========================================================================*/ - -USBHMassStorageLUNDriver MSBLKD[HAL_USBHMSD_MAX_LUNS]; - -static const struct USBHMassStorageDriverVMT blk_vmt = { - (bool (*)(void *))usbhmsdLUNIsInserted, - (bool (*)(void *))usbhmsdLUNIsProtected, - (bool (*)(void *))usbhmsdLUNConnect, - (bool (*)(void *))usbhmsdLUNDisconnect, - (bool (*)(void *, uint32_t, uint8_t *, uint32_t))usbhmsdLUNRead, - (bool (*)(void *, uint32_t, const uint8_t *, uint32_t))usbhmsdLUNWrite, - (bool (*)(void *))usbhmsdLUNSync, - (bool (*)(void *, BlockDeviceInfo *))usbhmsdLUNGetInfo -}; - - - -static uint32_t _requestsense(USBHMassStorageLUNDriver *lunp) { - scsi_sense_response_t sense; - msd_result_t res; - - res = scsi_requestsense(lunp, &sense); - if (res.tres != MSD_TRANSACTIONRESULT_OK) { - uerr("\tREQUEST SENSE: Transaction error"); - goto failed; - } else if (res.cres == MSD_COMMANDRESULT_FAILED) { - uerr("\tREQUEST SENSE: Command Failed"); - goto failed; - } else if (res.cres == MSD_COMMANDRESULT_PHASE_ERROR) { - //TODO: Do reset, etc. - uerr("\tREQUEST SENSE: Command Phase Error"); - goto failed; - } - - uerrf("\tREQUEST SENSE: Sense key=%x, ASC=%02x, ASCQ=%02x", - sense.byte[2] & 0xf, sense.byte[12], sense.byte[13]); - - return (sense.byte[2] & 0xf) | (sense.byte[12] << 8) | (sense.byte[13] << 16); - -failed: - return 0xffffffff; -} - -void usbhmsdLUNObjectInit(USBHMassStorageLUNDriver *lunp) { - osalDbgCheck(lunp != NULL); - memset(lunp, 0, sizeof(*lunp)); - lunp->vmt = &blk_vmt; - lunp->state = BLK_STOP; - /* Unnecessary because of the memset: - lunp->msdp = NULL; - lunp->next = NULL; - lunp->info.* = 0; - */ -} - -void usbhmsdLUNStart(USBHMassStorageLUNDriver *lunp) { - osalDbgCheck(lunp != NULL); - osalSysLock(); - osalDbgAssert((lunp->state == BLK_STOP) || (lunp->state == BLK_ACTIVE), - "invalid state"); - //TODO: complete - //lunp->state = BLK_ACTIVE; - osalSysUnlock(); -} - -void usbhmsdLUNStop(USBHMassStorageLUNDriver *lunp) { - osalDbgCheck(lunp != NULL); - osalSysLock(); - osalDbgAssert((lunp->state == BLK_STOP) || (lunp->state == BLK_ACTIVE), - "invalid state"); - //TODO: complete - //lunp->state = BLK_STOP; - osalSysUnlock(); -} - -bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp) { - USBHMassStorageDriver *const msdp = lunp->msdp; - msd_result_t res; - - osalDbgCheck(msdp != NULL); - osalSysLock(); - //osalDbgAssert((lunp->state == BLK_ACTIVE) || (lunp->state == BLK_READY), - // "invalid state"); - if (lunp->state == BLK_READY) { - osalSysUnlock(); - return HAL_SUCCESS; - } else if (lunp->state != BLK_ACTIVE) { - osalSysUnlock(); - return HAL_FAILED; - } - lunp->state = BLK_CONNECTING; - osalSysUnlock(); - - osalMutexLock(&msdp->mtx); - - USBH_DEFINE_BUFFER(union { - scsi_inquiry_response_t inq; - scsi_readcapacity10_response_t cap; }, u); - - uinfo("INQUIRY..."); - res = scsi_inquiry(lunp, &u.inq); - if (res.tres != MSD_TRANSACTIONRESULT_OK) { - uerr("\tINQUIRY: Transaction error"); - goto failed; - } else if (res.cres == MSD_COMMANDRESULT_FAILED) { - uerr("\tINQUIRY: Command Failed"); - _requestsense(lunp); - goto failed; - } else if (res.cres == MSD_COMMANDRESULT_PHASE_ERROR) { - //TODO: Do reset, etc. - uerr("\tINQUIRY: Command Phase Error"); - goto failed; - } - - uinfof("\tPDT=%02x", u.inq.peripheral & 0x1f); - if (u.inq.peripheral != 0) { - uerr("\tUnsupported PDT"); - goto failed; - } - - // Test if unit ready - uint8_t i; - for (i = 0; i < 10; i++) { - uinfo("TEST UNIT READY..."); - res = scsi_testunitready(lunp); - if (res.tres != MSD_TRANSACTIONRESULT_OK) { - uerr("\tTEST UNIT READY: Transaction error"); - goto failed; - } else if (res.cres == MSD_COMMANDRESULT_FAILED) { - uerr("\tTEST UNIT READY: Command Failed"); - _requestsense(lunp); - continue; - } else if (res.cres == MSD_COMMANDRESULT_PHASE_ERROR) { - //TODO: Do reset, etc. - uerr("\tTEST UNIT READY: Command Phase Error"); - goto failed; - } - uinfo("\tReady."); - break; - // osalThreadSleepMilliseconds(200); // will raise 'code is unreachable' warning - } - if (i == 10) goto failed; - - // Read capacity - uinfo("READ CAPACITY(10)..."); - res = scsi_readcapacity10(lunp, &u.cap); - if (res.tres != MSD_TRANSACTIONRESULT_OK) { - uerr("\tREAD CAPACITY(10): Transaction error"); - goto failed; - } else if (res.cres == MSD_COMMANDRESULT_FAILED) { - uerr("\tREAD CAPACITY(10): Command Failed"); - _requestsense(lunp); - goto failed; - } else if (res.cres == MSD_COMMANDRESULT_PHASE_ERROR) { - //TODO: Do reset, etc. - uerr("\tREAD CAPACITY(10): Command Phase Error"); - goto failed; - } - lunp->info.blk_size = __REV(u.cap.block_size); - lunp->info.blk_num = __REV(u.cap.last_block_addr) + 1; - uinfof("\tBlock size=%dbytes, blocks=%u (~%u MB)", lunp->info.blk_size, lunp->info.blk_num, - (uint32_t)(((uint64_t)lunp->info.blk_size * lunp->info.blk_num) / (1024UL * 1024UL))); - - uinfo("MSD Connected."); - - osalMutexUnlock(&msdp->mtx); - osalSysLock(); - lunp->state = BLK_READY; - osalSysUnlock(); - - return HAL_SUCCESS; - - /* Connection failed, state reset to BLK_ACTIVE.*/ -failed: - osalMutexUnlock(&msdp->mtx); - osalSysLock(); - lunp->state = BLK_ACTIVE; - osalSysUnlock(); - return HAL_FAILED; -} - - -bool usbhmsdLUNDisconnect(USBHMassStorageLUNDriver *lunp) { - osalDbgCheck(lunp != NULL); - osalSysLock(); - osalDbgAssert((lunp->state == BLK_ACTIVE) || (lunp->state == BLK_READY), - "invalid state"); - if (lunp->state == BLK_ACTIVE) { - osalSysUnlock(); - return HAL_SUCCESS; - } - lunp->state = BLK_DISCONNECTING; - osalSysUnlock(); - - //TODO: complete - - osalSysLock(); - lunp->state = BLK_ACTIVE; - osalSysUnlock(); - return HAL_SUCCESS; -} - -bool usbhmsdLUNRead(USBHMassStorageLUNDriver *lunp, uint32_t startblk, - uint8_t *buffer, uint32_t n) { - - osalDbgCheck(lunp != NULL); - bool ret = HAL_FAILED; - uint16_t blocks; - msd_result_t res; - - osalSysLock(); - if (lunp->state != BLK_READY) { - osalSysUnlock(); - return ret; - } - lunp->state = BLK_READING; - osalSysUnlock(); - - osalMutexLock(&lunp->msdp->mtx); - while (n) { - if (n > 0xffff) { - blocks = 0xffff; - } else { - blocks = (uint16_t)n; - } - res = scsi_read10(lunp, startblk, blocks, buffer); - if (res.tres != MSD_TRANSACTIONRESULT_OK) { - uerr("\tREAD (10): Transaction error"); - goto exit; - } else if (res.cres == MSD_COMMANDRESULT_FAILED) { - //TODO: request sense, and act appropriately - uerr("\tREAD (10): Command Failed"); - _requestsense(lunp); - goto exit; - } else if (res.cres == MSD_COMMANDRESULT_PHASE_ERROR) { - //TODO: Do reset, etc. - uerr("\tREAD (10): Command Phase Error"); - goto exit; - } - n -= blocks; - startblk += blocks; - buffer += blocks * lunp->info.blk_size; - } - - ret = HAL_SUCCESS; - -exit: - osalMutexUnlock(&lunp->msdp->mtx); - osalSysLock(); - if (lunp->state == BLK_READING) { - lunp->state = BLK_READY; - } else { - osalDbgCheck(lunp->state == BLK_STOP); - uwarn("MSD: State = BLK_STOP"); - } - osalSysUnlock(); - return ret; -} - -bool usbhmsdLUNWrite(USBHMassStorageLUNDriver *lunp, uint32_t startblk, - const uint8_t *buffer, uint32_t n) { - - osalDbgCheck(lunp != NULL); - bool ret = HAL_FAILED; - uint16_t blocks; - msd_result_t res; - - osalSysLock(); - if (lunp->state != BLK_READY) { - osalSysUnlock(); - return ret; - } - lunp->state = BLK_WRITING; - osalSysUnlock(); - - osalMutexLock(&lunp->msdp->mtx); - while (n) { - if (n > 0xffff) { - blocks = 0xffff; - } else { - blocks = (uint16_t)n; - } - res = scsi_write10(lunp, startblk, blocks, buffer); - if (res.tres != MSD_TRANSACTIONRESULT_OK) { - uerr("\tWRITE (10): Transaction error"); - goto exit; - } else if (res.cres == MSD_COMMANDRESULT_FAILED) { - //TODO: request sense, and act appropriately - uerr("\tWRITE (10): Command Failed"); - _requestsense(lunp); - goto exit; - } else if (res.cres == MSD_COMMANDRESULT_PHASE_ERROR) { - //TODO: Do reset, etc. - uerr("\tWRITE (10): Command Phase Error"); - goto exit; - } - n -= blocks; - startblk += blocks; - buffer += blocks * lunp->info.blk_size; - } - - ret = HAL_SUCCESS; - -exit: - osalMutexUnlock(&lunp->msdp->mtx); - osalSysLock(); - if (lunp->state == BLK_WRITING) { - lunp->state = BLK_READY; - } else { - osalDbgCheck(lunp->state == BLK_STOP); - uwarn("MSD: State = BLK_STOP"); - } - osalSysUnlock(); - return ret; -} - -bool usbhmsdLUNSync(USBHMassStorageLUNDriver *lunp) { - osalDbgCheck(lunp != NULL); - (void)lunp; - //TODO: Do SCSI Sync - return HAL_SUCCESS; -} - -bool usbhmsdLUNGetInfo(USBHMassStorageLUNDriver *lunp, BlockDeviceInfo *bdip) { - osalDbgCheck(lunp != NULL); - osalDbgCheck(bdip != NULL); - *bdip = lunp->info; - return HAL_SUCCESS; -} - -bool usbhmsdLUNIsInserted(USBHMassStorageLUNDriver *lunp) { - osalDbgCheck(lunp != NULL); - blkstate_t state; - osalSysLock(); - state = lunp->state; - osalSysUnlock(); - return (state >= BLK_ACTIVE); -} - -bool usbhmsdLUNIsProtected(USBHMassStorageLUNDriver *lunp) { - osalDbgCheck(lunp != NULL); - return FALSE; -} - -void usbhmsdObjectInit(USBHMassStorageDriver *msdp) { - osalDbgCheck(msdp != NULL); - memset(msdp, 0, sizeof(*msdp)); - msdp->info = &usbhmsdClassDriverInfo; - osalMutexObjectInit(&msdp->mtx); -} - -#endif diff --git a/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_uvc.c b/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_uvc.c deleted file mode 100644 index 09a0f1d..0000000 --- a/ChibiOS_16.1.5/community/os/hal/src/usbh/hal_usbh_uvc.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio - Copyright (C) 2015 Diego Ismirlian, TISA, (dismirlian (at) google's mail) - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#include "hal.h" -#include "hal_usbh.h" - -#if HAL_USBH_USE_UVC - -#if !HAL_USE_USBH -#error "USBHUVC needs HAL_USE_USBH" -#endif - -#if !HAL_USBH_USE_IAD -#error "USBHUVC needs HAL_USBH_USE_IAD" -#endif - -#if USBHUVC_DEBUG_ENABLE_TRACE -#define udbgf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define udbg(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define udbgf(f, ...) do {} while(0) -#define udbg(f, ...) do {} while(0) -#endif - -#if USBHUVC_DEBUG_ENABLE_INFO -#define uinfof(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define uinfo(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define uinfof(f, ...) do {} while(0) -#define uinfo(f, ...) do {} while(0) -#endif - -#if USBHUVC_DEBUG_ENABLE_WARNINGS -#define uwarnf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define uwarn(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define uwarnf(f, ...) do {} while(0) -#define uwarn(f, ...) do {} while(0) -#endif - -#if USBHUVC_DEBUG_ENABLE_ERRORS -#define uerrf(f, ...) usbDbgPrintf(f, ##__VA_ARGS__) -#define uerr(f, ...) usbDbgPuts(f, ##__VA_ARGS__) -#else -#define uerrf(f, ...) do {} while(0) -#define uerr(f, ...) do {} while(0) -#endif - - -static usbh_baseclassdriver_t *uvc_load(usbh_device_t *dev, - const uint8_t *descriptor, uint16_t rem); -static void uvc_unload(usbh_baseclassdriver_t *drv); - -static const usbh_classdriver_vmt_t class_driver_vmt = { - uvc_load, - uvc_unload -}; -const usbh_classdriverinfo_t usbhuvcClassDriverInfo = { - 0x0e, 0x03, 0x00, "UVC", &class_driver_vmt -}; - - -static usbh_baseclassdriver_t *uvc_load(usbh_device_t *dev, const uint8_t *descriptor, uint16_t rem) { - (void)dev; - (void)descriptor; - (void)rem; - return NULL; -} - -static void uvc_unload(usbh_baseclassdriver_t *drv) { - (void)drv; -} - -#endif - -- cgit v1.2.3