mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-26 06:53:52 +01:00
cpu/stm32/usbdev_fs: fix EP_REG(x) assignment for toggleable bits
EP_REG(x) registers have a total of 6 toggleable bits. Those bits can only be toggled if we write a one to it, otherwise writing a zero has no effect This commit fixes all the access to these registers to prevent from modifying these bits when not needed Signed-off-by: Dylan Laduranty <dylan.laduranty@mesotic.com>
This commit is contained in:
parent
164331eb0d
commit
701242d38d
@ -132,6 +132,10 @@ typedef struct {
|
||||
#error "_PMA_ACCESS_SCHEME is not defined"
|
||||
#endif
|
||||
|
||||
/* Bit mask containing all toggleable bits in a EP_REG(x) register */
|
||||
#define _EP_REG_TOGGLE_ONLY_BITS_MASK (USB_EP_DTOG_TX | USB_EP_DTOG_RX | \
|
||||
USB_EPTX_STAT | USB_EPRX_STAT )
|
||||
|
||||
#define EP_DESC ((ep_buf_desc_t*)USB1_PMAADDR)
|
||||
#define EP_REG(x) (*((volatile uint32_t*) (((uintptr_t)(USB)) + (4*x))))
|
||||
|
||||
@ -313,8 +317,9 @@ void USBDEV_ISR(void) {
|
||||
unsigned epnum = irq_status & 0x000F;
|
||||
usbdev_ep_t *ep = (irq_status & USB_ISTR_DIR) ? &_ep_out[epnum] : &_ep_in[epnum];
|
||||
/* get type and add endpoint address */
|
||||
uint16_t reg = _type_to_reg(ep->type) | ep->num;
|
||||
|
||||
uint16_t reg = (_type_to_reg(ep->type) | ep->num);
|
||||
/* Avoid toggling by mistake these bits */
|
||||
CLRBIT(reg, (_EP_REG_TOGGLE_ONLY_BITS_MASK));
|
||||
if (irq_status & USB_ISTR_DIR) {
|
||||
/* Clear RX CTR by writing 0, avoid clear TX CTR so leave it to one */
|
||||
EP_REG(epnum) = reg | USB_EP_CTR_TX;
|
||||
@ -422,8 +427,10 @@ static bool _ep_check(stm32_usbdev_fs_t *usbdev, unsigned idx,
|
||||
static void _ep_enable(usbdev_ep_t *ep)
|
||||
{
|
||||
uint16_t reg = EP_REG(ep->num);
|
||||
/* Avoid modification of the following registers */
|
||||
/* Avoid modification of the following bits in the register as writing
|
||||
1 has no effect on these bits */
|
||||
SETBIT(reg, USB_EP_CTR_RX | USB_EP_CTR_TX);
|
||||
CLRBIT(reg, USB_EP_DTOG_RX | USB_EP_DTOG_TX);
|
||||
if (ep->dir == USB_EP_DIR_OUT) {
|
||||
_set_ep_out_status(®, USB_EP_RX_NAK);
|
||||
/* Avoid toggling the other direction */
|
||||
@ -441,7 +448,8 @@ static void _ep_enable(usbdev_ep_t *ep)
|
||||
static void _ep_disable(usbdev_ep_t *ep)
|
||||
{
|
||||
uint16_t reg = EP_REG(ep->num);
|
||||
/* Avoid modification of the following registers */
|
||||
/* Avoid modification of the following bits in the register as writing
|
||||
1 has no effect on these bits */
|
||||
SETBIT(reg, USB_EP_CTR_RX | USB_EP_CTR_TX);
|
||||
|
||||
if (ep->dir == USB_EP_DIR_OUT) {
|
||||
@ -580,16 +588,17 @@ static void _usbdev_esr(usbdev_t *dev)
|
||||
|
||||
static void _usbdev_ep_init(usbdev_ep_t *ep)
|
||||
{
|
||||
uint16_t reg = EP_REG(ep->num);
|
||||
/* Set endpoint type */
|
||||
uint16_t reg = _type_to_reg(ep->type);
|
||||
/* Keep previous state if already set */
|
||||
reg |= EP_REG(ep->num) & (USB_EPTX_STAT | USB_EPRX_STAT);
|
||||
_set_ep_out_status(®, USB_EP_RX_VALID);
|
||||
reg &= ~(USB_EP_TYPE_MASK);
|
||||
reg |= _type_to_reg(ep->type);
|
||||
/* Keep the state ouf the other endpoint direction if already sets */
|
||||
CLRBIT(reg, _EP_REG_TOGGLE_ONLY_BITS_MASK);
|
||||
/* Assign EP address */
|
||||
reg |= (ep->num & 0x000F);
|
||||
/* Ensure interrupts are cleared */
|
||||
reg |= USB_EP_CTR_RX | USB_EP_CTR_TX;
|
||||
|
||||
reg &= ~(USB_EP_CTR_RX | USB_EP_CTR_TX);
|
||||
/* Write the configuration to the register */
|
||||
EP_REG(ep->num) = reg;
|
||||
if (ep->dir == USB_EP_DIR_IN) {
|
||||
EP_DESC[ep->num].addr_tx = _ep_in_buf[ep->num];
|
||||
@ -653,7 +662,8 @@ static int _usbdev_ep_get(usbdev_ep_t *ep, usbopt_ep_t opt,
|
||||
static void _ep_set_stall(usbdev_ep_t *ep, usbopt_enable_t enable)
|
||||
{
|
||||
uint16_t reg = EP_REG(ep->num);
|
||||
/* Avoid modification of the following registers */
|
||||
/* Avoid modification of the following bits in the register as writing
|
||||
1 has no effect on these bits */
|
||||
SETBIT(reg, USB_EP_CTR_RX | USB_EP_CTR_TX);
|
||||
|
||||
if (ep->dir == USB_EP_DIR_IN) {
|
||||
@ -742,11 +752,12 @@ static int _usbdev_ep_xmit(usbdev_ep_t *ep, uint8_t* buf, size_t len)
|
||||
{
|
||||
unsigned irq = irq_disable();
|
||||
uint16_t reg = EP_REG(ep->num);
|
||||
/* Avoid modification of the following registers */
|
||||
/* Avoid modification of the following bits in the register as writing
|
||||
1 has no effect on these bits */
|
||||
SETBIT(reg, USB_EP_CTR_RX | USB_EP_CTR_TX);
|
||||
if (ep->dir == USB_EP_DIR_OUT) {
|
||||
_set_ep_out_status(®, USB_EP_RX_VALID);
|
||||
_set_ep_in_status(®, USB_EP_TX_NAK);
|
||||
CLRBIT(reg, USB_EPTX_STAT);
|
||||
if (len == 0) {
|
||||
len = ep->len;
|
||||
}
|
||||
@ -761,8 +772,7 @@ static int _usbdev_ep_xmit(usbdev_ep_t *ep, uint8_t* buf, size_t len)
|
||||
_app_pbuf[ep->num] = buf;
|
||||
} else {
|
||||
_set_ep_in_status(®, USB_EP_TX_VALID);
|
||||
_set_ep_out_status(®, USB_EP_RX_VALID);
|
||||
|
||||
CLRBIT(reg, USB_EPRX_STAT);
|
||||
/* Transfer IN buffer content to USB PMA SRAM */
|
||||
uint16_t* pma_ptr = (uint16_t *)(USB1_PMAADDR +
|
||||
(EP_DESC[ep->num].addr_tx * _PMA_ACCESS_STEP_SIZE));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user