From cde7d1ce4d15ccb23db99ace2c0ac959bea7d864 Mon Sep 17 00:00:00 2001 From: Piotr Esden-Tempski Date: Fri, 8 Jan 2010 16:48:25 +0100 Subject: [PATCH] Added usb peripheral register definitions. It uses some tool macros defined in tools.h --- include/libopenstm32.h | 2 + include/libopenstm32/tools.h | 58 +++++++ include/libopenstm32/usb.h | 296 +++++++++++++++++++++++++++++++++++ 3 files changed, 356 insertions(+) create mode 100644 include/libopenstm32/tools.h create mode 100644 include/libopenstm32/usb.h diff --git a/include/libopenstm32.h b/include/libopenstm32.h index f0f7037d..f5c3026b 100644 --- a/include/libopenstm32.h +++ b/include/libopenstm32.h @@ -20,6 +20,7 @@ #ifndef LIBOPENSTM32_LIBOPENSTM32_H #define LIBOPENSTM32_LIBOPENSTM32_H +#include #include #include #include @@ -29,5 +30,6 @@ #include #include #include +#include #endif diff --git a/include/libopenstm32/tools.h b/include/libopenstm32/tools.h new file mode 100644 index 00000000..91c16b54 --- /dev/null +++ b/include/libopenstm32/tools.h @@ -0,0 +1,58 @@ +/* + * This file is part of the libopenstm32 project. + * + * Copyright (C) 2009 Piotr Esden-Tempski + * + * This program 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. + * + * This program 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 . + */ + +#ifndef LIBOPENSTM32_TOOLS_H +#define LIBOPENSTM32_TOOLS_H + +/****************************************************************************** + * Register accessors / manipulators + ******************************************************************************/ + +/* Get register content */ +#define GET_REG(REG) ((u16) *REG) +/* Set register content */ +#define SET_REG(REG, VAL) (*REG = (u16)VAL) +/* Clear register bit */ +#define CLR_REG_BIT(REG, BIT) SET_REG(REG, (~BIT)) +/* Clear register bit masking out some bits that must not be touched */ +#define CLR_REG_BIT_MSK(REG, MSK, BIT) SET_REG(REG, (GET_REG(REG) & \ + MSK & (~BIT))) +/* Get masked out bit value */ +#define GET_REG_BIT(REG, BIT) (GET_REG(REG) & BIT) + +/* + * Set/reset a bit in a masked window by using toggle mechanism. + * + * This means that we look at the bits in the bit window designated by + * the mask. If the bit in the masked window is not matching the + * bitmask BIT then we write 1 and if the bit in the masked window is + * matching the bitmask BIT we write 0. + * + * TODO: we may need a faster implementation of that one? + */ +#define TOG_SET_REG_BIT_MSK(REG, MSK, BIT) { \ + register u16 toggle_mask = GET_REG(REG) & MSK; \ + register u16 bit_selector; \ + for(bit_selector = 1; bit_selector; bit_selector <<= 1){ \ + if((bit_selector & BIT) != 0) toggle_mask ^= bit_selector; \ + } \ + SET_REG(REG, toggle_mask); \ + } + +#endif /* LIBOPENSTM32_TOOLS_H */ diff --git a/include/libopenstm32/usb.h b/include/libopenstm32/usb.h new file mode 100644 index 00000000..660833e8 --- /dev/null +++ b/include/libopenstm32/usb.h @@ -0,0 +1,296 @@ +/* + * This file is part of the libopenstm32 project. + * + * Copyright (C) 2009 Piotr Esden-Tempski + * + * This program 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. + * + * This program 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 . + */ + +#ifndef LIBOPENSTM32_USB_H +#define LIBOPENSTM32_USB_H + +/****************************************************************************** + * USB base addresses + ******************************************************************************/ + +#define USB_PMA_BASE (0x40006000L) /* USB packet buffer memory base + address */ + +/****************************************************************************** + * USB general registers + ******************************************************************************/ + +/* USB Control register */ +#define USB_CNTR_REG ((volatile u32 *)(USB_DEV_FS_BASE + 0x40)) +/* USB Interrupt status register */ +#define USB_ISTR_REG ((volatile u32 *)(USB_DEV_FS_BASE + 0x44)) +/* USB Frame number register */ +#define USB_FNR_REG ((volatile u32 *)(USB_DEV_FS_BASE + 0x48)) +/* USB Device address register */ +#define USB_DADDR_REG ((volatile u32 *)(USB_DEV_FS_BASE + 0x4C)) +/* USB Buffer table address register */ +#define USB_BTABLE_REG ((volatile u32 *)(USB_DEV_FS_BASE + 0x50)) +/* USB EP register */ +#define USB_EP_REG(EP) ((volatile u32 *)(USB_DEV_FS_BASE + EP)) + +/****************************************************************************** + * USB control register masks / bits + ******************************************************************************/ + +/* Interrupt mask bits, set to 1 to enable interrupt generation */ +#define USB_CNTR_CTRM (0x8000) +#define USB_CNTR_PMAOVRM (0x4000) +#define USB_CNTR_ERRM (0x2000) +#define USB_CNTR_WKUPM (0x1000) +#define USB_CNTR_SUSPM (0x0800) +#define USB_CNTR_RESETM (0x0400) +#define USB_CNTR_SOFM (0x0200) +#define USB_CNTR_ESOFM (0x0100) + +/* Request/Force bits */ + +#define USB_CNTR_RESUME (0x0010) /* Resume request */ +#define USB_CNTR_FSUSP (0x0008) /* Force suspend */ +#define USB_CNTR_LP_MODE (0x0004) /* Low-power mode */ +#define USB_CNTR_PWDN (0x0002) /* Power down */ +#define USB_CNTR_FRES (0x0001) /* Force reset */ + +/****************************************************************************** + * USB interrupt status register masks / bits + ******************************************************************************/ + +#define USB_ISTR_CTR 0x8000 /* Correct Transfer */ +#define USB_ISTR_PMAOVR 0x4000 /* Packet Memory Area Over / Underrun */ +#define USB_ISTR_ERR 0x2000 /* Error */ +#define USB_ISTR_WKUP 0x1000 /* Wake up */ +#define USB_ISTR_SUSP 0x0800 /* Suspend mode request */ +#define USB_ISTR_RESET 0x0400 /* USB RESET request */ +#define USB_ISTR_SOF 0x0200 /* Start Of Frame */ +#define USB_ISTR_ESOF 0x0100 /* Expected Start Of Frame */ +#define USB_ISTR_DIR 0x0010 /* Direction of transaction */ +#define USB_ISTR_EP_ID 0x000F /* Endpoint Identifier */ + +/****************************************************************************** + * USB interrupt status register manipulators + ******************************************************************************/ + +//#define USB_CLR_ISTR_CTR() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_CTR) /* CTR is read only! */ +#define USB_CLR_ISTR_PMAOVR() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_PMAOVR) +#define USB_CLR_ISTR_ERR() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_ERR) +#define USB_CLR_ISTR_WKUP() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_WKUP) +#define USB_CLR_ISTR_SUSP() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_SUSP) +#define USB_CLR_ISTR_RESET() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_RESET) +#define USB_CLR_ISTR_SOF() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_SOF) +#define USB_CLR_ISTR_ESOF() CLR_REG_BIT(USB_ISTR_REG, USB_ISTR_ESOF) + +/****************************************************************************** + * USB device addres register masks / bits + ******************************************************************************/ + +#define USB_DADDR_ENABLE 0x0080 +#define USB_DADDR_ADDR 0x007F + +/****************************************************************************** + * USB device addres register manipulators + ******************************************************************************/ + +/****************************************************************************** + * USB endpoint register offsets + ******************************************************************************/ + +#define USB_EP0 ((u8)0) +#define USB_EP1 ((u8)1) +#define USB_EP2 ((u8)2) +#define USB_EP3 ((u8)3) +#define USB_EP4 ((u8)4) +#define USB_EP5 ((u8)5) +#define USB_EP6 ((u8)6) +#define USB_EP7 ((u8)7) + +/****************************************************************************** + * USB endpoint register masks / bits + ******************************************************************************/ + +/* masks and toggle bits */ +#define USB_EP_RX_CTR (0x8000) /* Correct transfer RX */ +#define USB_EP_RX_DTOG (0x4000) /* Data toggle RX */ +#define USB_EP_RX_STAT (0x3000) /* Endpoint status for RX */ + +#define USB_EP_SETUP (0x0800) /* Setup transaction completed */ +#define USB_EP_TYPE (0x0600) /* Endpoint type */ +#define USB_EP_KIND (0x0100) /* Endpoint kind. + * When set and type=bulk -> double buffer + * When set and type=control -> status out + */ + +#define USB_EP_TX_CTR (0x0080) /* Correct transfer TX */ +#define USB_EP_TX_DTOG (0x0040) /* Data toggle TX */ +#define USB_EP_TX_STAT (0x0030) /* Endpoint status for TX */ + +#define USB_EP_ADDR (0x000F) /* Endpoint Address */ + +/* Masking all toggle bits */ +#define USB_EP_NTOGGLE_MSK (USB_EP_RX_CTR | \ + USB_EP_SETUP | \ + USB_EP_TYPE | \ + USB_EP_KIND | \ + USB_EP_TX_CTR | \ + USB_EP_ADDR) + +/* All non toggle bits plus EP_RX toggle bits */ +#define USB_EP_RX_STAT_TOG_MSK (USB_EP_RX_STAT | USB_EP_NTOGGLE_MSK) +/* All non toggle bits plus EP_TX toggle bits */ +#define USB_EP_TX_STAT_TOG_MSK (USB_EP_TX_STAT | USB_EP_NTOGGLE_MSK) + +/* Endpoint status bits for USB_EP_RX_STAT bit field */ +#define USB_EP_RX_STAT_DISABLED (0x0000) +#define USB_EP_RX_STAT_STALL (0x1000) +#define USB_EP_RX_STAT_NAK (0x2000) +#define USB_EP_RX_STAT_VALID (0x3000) + +/* Endpoint status bits for USB_EP_TX_STAT bit field */ +#define USB_EP_TX_STAT_DISABLED (0x0000) +#define USB_EP_TX_STAT_STALL (0x0010) +#define USB_EP_TX_STAT_NAK (0x0020) +#define USB_EP_TX_STAT_VALID (0x0030) + +/* Endpoint type bits for USB_EP_TYPE bit field */ +#define USB_EP_TYPE_BULK (0x0000) +#define USB_EP_TYPE_CONTROL (0x0200) +#define USB_EP_TYPE_ISO (0x0400) +#define USB_EP_TYPE_INTERRUPT (0x0600) + +/****************************************************************************** + * USB endpoint register manipulators + ******************************************************************************/ + +/* Set USB endpoint tx/rx status. + * + * USB status field is changed using an awkward toggle mechanism, that + * is why we use some helper macros for that. + */ +#define USB_SET_EP_RX_STAT(EP, STAT) \ + TOG_SET_REG_BIT_MSK(USB_EP_REG(EP), \ + USB_EP_RX_STAT_TOG_MSK, \ + STAT) + +#define USB_SET_EP_TX_STAT(EP, STAT) \ + TOG_SET_REG_BIT_MSK(USB_EP_REG(EP), \ + USB_EP_TX_STAT_TOG_MSK, \ + STAT) + +/* Macros for clearing and setting USB endpoint register bits that do + * not use the toggle mechanism. + * + * Because the register contains some bits that use the toggle + * mechanism we need a helper macro here. Otherwise the code gets + * really messy. + */ +#define USB_CLR_EP_NTOGGLE_BIT(EP, BIT) \ + CLR_REG_BIT_MSK(USB_EP_REG(EP), \ + USB_EP_NTOGGLE_MSK, \ + BIT) + +#define USB_CLR_EP_RX_CTR(EP) \ + USB_CLR_EP_NTOGGLE_BIT(EP, \ + USB_EP_RX_CTR) + +#define USB_CLR_EP_TX_CTR(EP) \ + USB_CLR_EP_NTOGGLE_BIT(EP, \ + USB_EP_TX_CTR) + +#define USB_SET_EP_TYPE(EP, TYPE) \ + SET_REG(USB_EP_REG(EP), \ + (GET_REG(USB_EP_REG(EP)) & \ + (USB_EP_NTOGGLE_MSK & \ + (~USB_EP_TYPE))) | TYPE) + +#define USB_SET_EP_KIND(EP) \ + SET_REG(USB_EP_REG(EP), \ + (GET_REG(USB_EP_REG(EP)) & \ + (USB_EP_NTOGGLE_MSK & \ + (~USB_EP_KIND))) | USB_EP_KIND) + +#define USB_CLR_EP_KIND(EP) \ + SET_REG(USB_EP_REG(EP), \ + (GET_REG(USB_EP_REG(EP)) & \ + (USB_EP_NTOGGLE_MSK & \ + (~USB_EP_KIND)))) + +#define USB_SET_EP_STAT_OUT(EP) \ + USB_SET_EP_KIND(EP) + +#define USB_CLR_EP_STAT_OUT(EP) \ + USB_CLR_EP_KIND(EP) + +#define USB_SET_EP_ADDR(EP, ADDR) \ + SET_REG(USB_EP_REG(EP), \ + ((GET_REG(USB_EP_REG(EP)) & \ + (USB_EP_NTOGGLE_MSK & \ + (~USB_EP_ADDR))) | ADDR)) + +/****************************************************************************** + * USB BTABLE registers + ******************************************************************************/ +#define USB_GET_BTABLE GET_REG(USB_BTABLE_REG) + +#define USB_EP_TX_ADDR(EP) ((u32 *)(USB_PMA_BASE + \ + (USB_GET_BTABLE+EP*8 ) * 2)) + +#define USB_EP_TX_COUNT(EP) ((u32 *)(USB_PMA_BASE + \ + (USB_GET_BTABLE+EP*8+2) * 2)) + +#define USB_EP_RX_ADDR(EP) ((u32 *)(USB_PMA_BASE + \ + (USB_GET_BTABLE+EP*8+4) * 2)) + +#define USB_EP_RX_COUNT(EP) ((u32 *)(USB_PMA_BASE + \ + (USB_GET_BTABLE+EP*8+6) * 2)) + +/****************************************************************************** + * USB BTABLE manipulators + ******************************************************************************/ + +#define USB_GET_EP_TX_ADDR(EP) \ + GET_REG(USB_EP_TX_ADDR(EP)) + +#define USB_GET_EP_TX_COUNT(EP) \ + GET_REG(USB_EP_TX_COUNT(EP)) + +#define USB_GET_EP_RX_ADDR(EP) \ + GET_REG(USB_EP_RX_ADDR(EP)) + +#define USB_GET_EP_RX_COUNT(EP) \ + GET_REG(USB_EP_RX_COUNT(EP)) + +#define USB_SET_EP_TX_ADDR(EP, ADDR) \ + SET_REG(USB_EP_TX_ADDR(EP), ADDR) + +#define USB_SET_EP_TX_COUNT(EP, COUNT) \ + SET_REG(USB_EP_TX_COUNT(EP), COUNT) + +#define USB_SET_EP_RX_ADDR(EP, ADDR) \ + SET_REG(USB_EP_RX_ADDR(EP), ADDR) + +#define USB_SET_EP_RX_COUNT(EP, COUNT) \ + SET_REG(USB_EP_RX_COUNT(EP), COUNT) + +#define USB_GET_EP_TX_BUFF(EP) \ + (USB_PMA_BASE + \ + (u8 *)(USB_GET_EP_TX_ADDR(EP) * 2)) + +#define USB_GET_EP_RX_BUFF(EP) \ + (USB_PMA_BASE + \ + (u8 *)(USB_GET_EP_RX_ADDR(EP) * 2)) + +#endif /* LIBOPENSTM32_USB_H */